text: /*
   * surfaces_general.h
   *
   *  Created on: Jun 26, 2021
   *      Author: betten
   */
  
  #ifndef SRC_LIB_TOP_LEVEL_SURFACES_SURFACES_GENERAL_SURFACES_GENERAL_H_
  #define SRC_LIB_TOP_LEVEL_SURFACES_SURFACES_GENERAL_SURFACES_GENERAL_H_
  
  
  
  namespace orbiter {
  namespace top_level {
  
  
  
  // #############################################################################
  // cubic_surface_activity_description.cpp
  // #############################################################################
  
  //! description of an activity associated with a cubic surface
  
  
  class cubic_surface_activity_description {
  public:
  
  	int f_report;
  
  	int f_report_with_group;
  
  	int f_export_points;
  
  	int f_clebsch;
  
  	int f_codes;
  
  	int f_all_quartic_curves;
  
  	int f_export_all_quartic_curves;
  
  	cubic_surface_activity_description();
  	~cubic_surface_activity_description();
  	int read_arguments(
  		int argc, std::string *argv,
  		int verbose_level);
  	void print();
  
  };
  
  // #############################################################################
  // cubic_surface_activity.cpp
  // #############################################################################
  
  //! an activity associated with a cubic surface
  
  
  class cubic_surface_activity {
  public:
  
  	cubic_surface_activity_description *Descr;
  	surface_create *SC;
  
  
  	cubic_surface_activity();
  	~cubic_surface_activity();
  	void init(cubic_surface_activity_description *Cubic_surface_activity_description,
  			surface_create *SC, int verbose_level);
  	void perform_activity(int verbose_level);
  };
  
  
  
  
  // #############################################################################
  // surface_clebsch_map.cpp
  // #############################################################################
  
  //! a Clebsch map associated with a cubic surface and a choice of half double six
  
  
  class surface_clebsch_map {
  public:
  
  	surface_object_with_action *SOA;
  
  	int orbit_idx;
  	int f, l, hds;
  
  	clebsch_map *Clebsch_map;
  
  
  	surface_clebsch_map();
  	~surface_clebsch_map();
  	void report(std::ostream &ost, int verbose_level);
  	void init(surface_object_with_action *SOA, int orbit_idx, int verbose_level);
  
  };
  
  
  // #############################################################################
  // surface_create.cpp
  // #############################################################################
  
  
  //! to create a cubic surface from a description using class surface_create_description
  
  
  class surface_create {
  
  public:
  	surface_create_description *Descr;
  
  	std::string prefix;
  	std::string label_txt;
  	std::string label_tex;
  
  	int f_ownership;
  
  	int q;
  	finite_field *F;
  
  	int f_semilinear;
  
  	surface_domain *Surf;
  
  	surface_with_action *Surf_A;
  
  	surface_object *SO;
  
  	int f_has_group;
  	strong_generators *Sg;
  	int f_has_nice_gens;
  	vector_ge *nice_gens;
  
  
  
  
  	surface_create();
  	~surface_create();
  	void null();
  	void freeself();
  	void init_with_data(surface_create_description *Descr,
  		surface_with_action *Surf_A,
  		int verbose_level);
  	void init(surface_create_description *Descr,
  		surface_with_action *Surf_A,
  		int verbose_level);
  	void create_surface_from_description(int verbose_level);
  	void override_group(std::string &group_order_text,
  			int nb_gens, std::string &gens_text, int verbose_level);
  	void create_Eckardt_surface(int a, int b, int verbose_level);
  	void create_surface_G13(int a, int verbose_level);
  	void create_surface_F13(int a, int verbose_level);
  	void create_surface_bes(int a, int c, int verbose_level);
  	void create_surface_general_abcd(int a, int b, int c, int d, int verbose_level);
  	void create_surface_by_coefficients(std::string &coefficients_text,
  			std::vector<std::string> &select_double_six_string,
  			int verbose_level);
  	void create_surface_by_coefficient_vector(int *coeffs20,
  			std::vector<std::string> &select_double_six_string,
  			int verbose_level);
  	void create_surface_by_rank(std::string &rank_text, int defining_q,
  			std::vector<std::string> &select_double_six_string,
  			int verbose_level);
  	void create_surface_from_catalogue(int iso,
  			std::vector<std::string> &select_double_six_string,
  			int verbose_level);
  	void create_surface_by_arc_lifting(
  			std::string &arc_lifting_text,
  			int verbose_level);
  	void create_surface_by_arc_lifting_with_two_lines(
  			std::string &arc_lifting_text,
  			std::string &arc_lifting_two_lines_text,
  			int verbose_level);
  	void create_surface_Cayley_form(
  			int k, int l, int m, int n,
  			int verbose_level);
  	void create_surface_by_equation(
  			std::string &name_of_formula,
  			std::string &name_of_formula_tex,
  			std::string &managed_variables,
  			std::string &equation_text,
  			std::string &equation_parameters,
  			std::string &equation_parameters_tex,
  			std::vector<std::string> &select_double_six_string,
  			int verbose_level);
  	void create_surface_by_double_six(
  			std::string &by_double_six_label,
  			std::string &by_double_six_label_tex,
  			std::string &by_double_six_text,
  			int verbose_level);
  	void create_surface_by_skew_hexagon(
  			std::string &given_label,
  			std::string &given_label_tex,
  			int verbose_level);
  	void apply_transformations(
  		std::vector<std::string> &transform_coeffs,
  		std::vector<int> &f_inverse_transform,
  		int verbose_level);
  	void compute_group(projective_space_with_action *PA,
  			int verbose_level);
  
  };
  
  
  // #############################################################################
  // surface_create_description.cpp
  // #############################################################################
  
  
  
  //! to describe a cubic surface from the command line
  
  
  class surface_create_description {
  
  public:
  
  	int f_q;
  	int q;
  
  	int f_label_txt;
  	std::string label_txt;
  
  	int f_label_tex;
  	std::string label_tex;
  
  	int f_label_for_summary;
  	std::string label_for_summary;
  
  	int f_catalogue;
  	int iso;
  	int f_by_coefficients;
  	std::string coefficients_text;
  
  	int f_by_rank;
  	std::string rank_text;
  	int rank_defining_q;
  
  	int f_family_Eckardt;
  	int family_Eckardt_a;
  	int family_Eckardt_b;
  
  	int f_family_G13;
  	int family_G13_a;
  
  	int f_family_F13;
  	int family_F13_a;
  
  	int f_family_bes;
  	int family_bes_a;
  	int family_bes_c;
  
  	int f_family_general_abcd;
  	int family_general_abcd_a;
  	int family_general_abcd_b;
  	int family_general_abcd_c;
  	int family_general_abcd_d;
  
  	int f_arc_lifting;
  	std::string arc_lifting_text;
  	std::string arc_lifting_two_lines_text;
  
  	int f_arc_lifting_with_two_lines;
  	std::vector<std::string> select_double_six_string;
  
  	int f_Cayley_form;
  	int Cayley_form_k;
  	int Cayley_form_l;
  	int Cayley_form_m;
  	int Cayley_form_n;
  
  
  	int f_by_equation;
  	std::string equation_name_of_formula;
  	std::string equation_name_of_formula_tex;
  	std::string equation_managed_variables;
  	std::string equation_text;
  	std::string equation_parameters;
  	std::string equation_parameters_tex;
  
  
  	int f_by_double_six;
  	std::string by_double_six_label;
  	std::string by_double_six_label_tex;
  	std::string by_double_six_text;
  
  	int f_by_skew_hexagon;
  	std::string by_skew_hexagon_label;
  	std::string by_skew_hexagon_label_tex;
  
  	int f_override_group;
  	std::string override_group_order;
  	int override_group_nb_gens;
  	std::string override_group_gens;
  
  	std::vector<std::string> transform_coeffs;
  	std::vector<int> f_inverse_transform;
  
  
  
  	surface_create_description();
  	~surface_create_description();
  	void null();
  	void freeself();
  	int read_arguments(int argc, std::string *argv,
  		int verbose_level);
  	void print();
  	int get_q();
  };
  
  
  // #############################################################################
  // surface_domain_high_level.cpp
  // #############################################################################
  
  
  //! high level functions for cubic surfaces
  
  
  class surface_domain_high_level {
  
  public:
  
  
  	surface_domain_high_level();
  	~surface_domain_high_level();
  
  	void do_sweep_4(
  			projective_space_with_action *PA,
  			surface_create_description *Surface_Descr,
  			std::string &sweep_fname,
  			int verbose_level);
  	void do_sweep_4_27(
  			projective_space_with_action *PA,
  			surface_create_description *Surface_Descr,
  			std::string &sweep_fname,
  			int verbose_level);
  #if 0
  	void do_create_surface(
  			projective_space_with_action *PA,
  			surface_create_description *Surface_Descr,
  			poset_classification_control *Control_six_arcs,
  			int verbose_level);
  #endif
  	void classify_surfaces_with_double_sixes(
  			projective_space_with_action *PA,
  			poset_classification_control *Control,
  			surface_classify_wedge *&SCW,
  			int verbose_level);
  	void prepare_surface_classify_wedge(
  			finite_field *F,
  			projective_space_with_action *PA,
  			poset_classification_control *Control,
  			surface_domain *&Surf, surface_with_action *&Surf_A,
  			surface_classify_wedge *&SCW,
  			int verbose_level);
  	void do_study_surface(finite_field *F, int nb, int verbose_level);
  	void do_classify_surfaces_through_arcs_and_two_lines(
  			projective_space_with_action *PA,
  			poset_classification_control *Control_six_arcs,
  			int f_test_nb_Eckardt_points, int nb_E,
  			int verbose_level);
  	void do_classify_surfaces_through_arcs_and_trihedral_pairs(
  			projective_space_with_action *PA,
  			poset_classification_control *Control1,
  			poset_classification_control *Control2,
  			poset_classification_control *Control_six_arcs,
  			int f_test_nb_Eckardt_points, int nb_E,
  			int verbose_level);
  	void do_six_arcs(
  			projective_space_with_action *PA,
  			poset_classification_control *Control_six_arcs,
  			int f_filter_by_nb_Eckardt_points, int nb_Eckardt_points,
  			int verbose_level);
  	void do_cubic_surface_properties(
  			projective_space_with_action *PA,
  			std::string &fname_csv, int defining_q,
  			int column_offset,
  			int verbose_level);
  	void do_cubic_surface_properties_analyze(
  			projective_space_with_action *PA,
  			std::string &fname_csv, int defining_q,
  			int verbose_level);
  	void report_singular_surfaces(std::ostream &ost,
  			struct cubic_surface_data_set *Data, int nb_orbits, int verbose_level);
  	void report_non_singular_surfaces(std::ostream &ost,
  			struct cubic_surface_data_set *Data, int nb_orbits, int verbose_level);
  	void report_surfaces_by_lines(std::ostream &ost,
  			struct cubic_surface_data_set *Data, tally &T, int verbose_level);
  	void do_create_surface_reports(std::string &field_orders_text, int verbose_level);
  	void do_create_surface_atlas(int q_max, int verbose_level);
  	void do_create_surface_atlas_q_e(int q_max,
  			struct table_surfaces_field_order *T, int nb_e, int *Idx, int nb,
  			std::string &fname_report_tex,
  			int verbose_level);
  	void do_create_dickson_atlas(int verbose_level);
  	void make_fname_surface_report_tex(std::string &fname, int q, int ocn);
  	void make_fname_surface_report_pdf(std::string &fname, int q, int ocn);
  
  };
  
  
  // #############################################################################
  // surface_object_with_action.cpp
  // #############################################################################
  
  
  //! an instance of a cubic surface together with its stabilizer
  
  
  class surface_object_with_action {
  
  public:
  
  	int q;
  	finite_field *F; // do not free
  
  	surface_domain *Surf; // do not free
  	surface_with_action *Surf_A; // do not free
  
  	surface_object *SO; // do not free
  	strong_generators *Aut_gens;
  		// generators for the automorphism group
  
  	int f_has_nice_gens;
  	vector_ge *nice_gens;
  
  	strong_generators *projectivity_group_gens;
  	sylow_structure *Syl;
  
  	action *A_on_points;
  	action *A_on_Eckardt_points;
  	action *A_on_Double_points;
  	action *A_on_the_lines;
  	action *A_single_sixes;
  	action *A_on_tritangent_planes;
  	action *A_on_Hesse_planes;
  	action *A_on_trihedral_pairs;
  	action *A_on_pts_not_on_lines;
  
  
  	schreier *Orbits_on_points;
  	schreier *Orbits_on_Eckardt_points;
  	schreier *Orbits_on_Double_points;
  	schreier *Orbits_on_lines;
  	schreier *Orbits_on_single_sixes;
  	schreier *Orbits_on_tritangent_planes;
  	schreier *Orbits_on_Hesse_planes;
  	schreier *Orbits_on_trihedral_pairs;
  	schreier *Orbits_on_points_not_on_lines;
  
  
  
  	surface_object_with_action();
  	~surface_object_with_action();
  	void null();
  	void freeself();
  	void init_equation(surface_with_action *Surf_A, int *eqn,
  		strong_generators *Aut_gens, int verbose_level);
  	void init_with_group(surface_with_action *Surf_A,
  		long int *Lines, int nb_lines, int *eqn,
  		strong_generators *Aut_gens,
  		int f_find_double_six_and_rearrange_lines,
  		int f_has_nice_gens, vector_ge *nice_gens,
  		int verbose_level);
  	void init_with_surface_object(surface_with_action *Surf_A,
  			surface_object *SO,
  			strong_generators *Aut_gens,
  			int f_has_nice_gens, vector_ge *nice_gens,
  			int verbose_level);
  	void init_surface_object(surface_with_action *Surf_A,
  		surface_object *SO,
  		strong_generators *Aut_gens, int verbose_level);
  	void compute_projectivity_group(int verbose_level);
  	void compute_orbits_of_automorphism_group(int verbose_level);
  	void init_orbits_on_points(int verbose_level);
  	void init_orbits_on_Eckardt_points(int verbose_level);
  	void init_orbits_on_Double_points(int verbose_level);
  	void init_orbits_on_lines(int verbose_level);
  	void init_orbits_on_half_double_sixes(int verbose_level);
  	void init_orbits_on_tritangent_planes(int verbose_level);
  	void init_orbits_on_Hesse_planes(int verbose_level);
  	void init_orbits_on_trihedral_pairs(int verbose_level);
  	void init_orbits_on_points_not_on_lines(int verbose_level);
  	void print_generators_on_lines(
  			std::ostream &ost,
  			strong_generators *Aut_gens,
  			int verbose_level);
  	void print_elements_on_lines(
  			std::ostream &ost,
  			strong_generators *Aut_gens,
  			int verbose_level);
  	void print_automorphism_group(std::ostream &ost,
  		int f_print_orbits, std::string &fname_mask,
  		layered_graph_draw_options *Opt,
  		int verbose_level);
  	void cheat_sheet_basic(std::ostream &ost, int verbose_level);
  	void cheat_sheet(std::ostream &ost,
  			std::string &label_txt,
  			std::string &label_tex,
  			int f_print_orbits, std::string &fname_mask,
  			layered_graph_draw_options *Opt,
  			int verbose_level);
  	void print_automorphism_group_gnerators(std::ostream &ost, int verbose_level);
  	void investigate_surface_and_write_report(
  			layered_graph_draw_options *Opt,
  			action *A,
  			surface_create *SC,
  			six_arcs_not_on_a_conic *Six_arcs,
  			int verbose_level);
  	void investigate_surface_and_write_report2(
  			std::ostream &ost,
  			layered_graph_draw_options *Opt,
  			action *A,
  			surface_create *SC,
  			six_arcs_not_on_a_conic *Six_arcs,
  			std::string &fname_mask,
  			std::string &label,
  			std::string &label_tex,
  			int verbose_level);
  	void all_quartic_curves(
  			std::string &surface_prefix,
  			std::ostream &ost,
  			std::ostream &ost_quartics,
  			int verbose_level);
  	void export_all_quartic_curves(
  			std::string &surface_prefix,
  			std::ostream &ost_quartics_csv,
  			int verbose_level);
  	void print_full_del_Pezzo(std::ostream &ost, int verbose_level);
  };
  
  // #############################################################################
  // surface_study.cpp
  // #############################################################################
  
  //! to study properties of cubic surfaces
  
  class surface_study {
  public:
  	int q;
  	int nb;
  	int *rep;
  	std::string prefix;
  	finite_field *F;
  	surface_domain *Surf;
  
  	int nb_lines_PG_3;
  
  	int *data;
  	int nb_gens;
  	int data_size;
  	const char *stab_order;
  
  	action *A;
  	action *A2;
  	sims *S;
  	long int *Lines;
  	int *coeff;
  
  	int f_semilinear;
  
  	set_and_stabilizer *SaS;
  
  
  	// line orbits:
  	int *orbit_first;
  	int *orbit_length;
  	int *orbit;
  	int nb_orbits;
  
  
  	// orbit_on_lines:
  	action *A_on_lines;
  	schreier *Orb;
  	int shortest_line_orbit_idx;
  
  	// for study_find_eckardt_points:
  	int *Adj;
  	int *R;
  	long int *Intersection_pt;
  	long int *Double_pts;
  	int nb_double_pts;
  	long int *Eckardt_pts;
  	int nb_Eckardt_pts;
  
  
  	void init(finite_field *F, int nb, int verbose_level);
  	void study_intersection_points(int verbose_level);
  	void study_line_orbits(int verbose_level);
  	void study_group(int verbose_level);
  	void study_orbits_on_lines(int verbose_level);
  	void study_find_eckardt_points(int verbose_level);
  	void study_surface_with_6_eckardt_points(int verbose_level);
  };
  
  
  void move_point_set(action *A2,
  	set_and_stabilizer *Universe, long int *Pts, int nb_pts,
  	int *Elt, set_and_stabilizer *&new_stab,
  	int verbose_level);
  void matrix_entry_print(long int *p,
  		int m, int n, int i, int j, int val,
  		std::string &output, void *data);
  
  
  
  // #############################################################################
  // surface_with_action.cpp
  // #############################################################################
  
  //! cubic surfaces in projective space with automorphism group
  
  
  
  class surface_with_action {
  
  public:
  
  
  	projective_space_with_action *PA;
  
  	int f_semilinear;
  
  	surface_domain *Surf; // do not free
  
  	action *A; // linear group PGGL(4,q)
  
  	action *A_wedge; // linear group PGGL(4,q)
  
  
  	action *A2; // linear group PGGL(4,q) acting on lines
  	action *A_on_planes; // linear group PGGL(4,q) acting on planes
  
  	int *Elt1;
  
  	action_on_homogeneous_polynomials *AonHPD_3_4;
  
  
  	classify_trihedral_pairs *Classify_trihedral_pairs;
  
  	recoordinatize *Recoordinatize;
  	long int *regulus; // [regulus_size]
  	int regulus_size; // q + 1
  
  
  	surface_with_action();
  	~surface_with_action();
  	void null();
  	void freeself();
  	void init(surface_domain *Surf,
  			projective_space_with_action *PA,
  			int f_recoordinatize,
  			int verbose_level);
  	long int apply_null_polarity(
  		long int a, int verbose_level);
  	long int apply_polarity(
  		long int a, int *Polarity36, int verbose_level);
  	void complete_skew_hexagon(
  		long int *skew_hexagon,
  		std::vector<std::vector<long int> > &Double_sixes,
  		int verbose_level);
  	void complete_skew_hexagon_with_polarity(
  			std::string &label_for_printing,
  		long int *skew_hexagon,
  		int *Polarity36,
  		std::vector<std::vector<long int> > &Double_sixes,
  		int verbose_level);
  	void create_regulus_and_opposite_regulus(
  		long int *three_skew_lines, long int *&regulus, long int *&opp_regulus, int &regulus_sz,
  		int verbose_level);
  	int create_double_six_safely(
  		long int *five_lines, long int transversal_line,
  		long int *double_six, int verbose_level);
  	int create_double_six_from_five_lines_with_a_common_transversal(
  		long int *five_lines, long int transversal_line,
  		long int *double_six, int verbose_level);
  	void report_basics(std::ostream &ost);
  	void report_double_triplets(std::ostream &ost);
  	void report_double_triplets_detailed(std::ostream &ost);
  	void create_surface(
  			surface_create_description *Surface_Descr,
  			surface_create *&SC,
  			int verbose_level);
  	void create_surface_and_do_report(
  			surface_create_description *Surface_Descr,
  			int f_has_control_six_arcs, poset_classification_control *Control_six_arcs,
  			int verbose_level);
  	void test_group(
  			surface_create *SC,
  			int verbose_level);
  	void report_with_group(
  			surface_create *SC,
  			int f_has_control_six_arcs, poset_classification_control *Control_six_arcs,
  			int verbose_level);
  	void create_surface_object_with_action(
  			surface_create *SC,
  			surface_object_with_action *&SoA,
  			int verbose_level);
  	void export_points(
  			surface_create *SC,
  			int verbose_level);
  	void do_report(
  			surface_create *SC,
  			int verbose_level);
  	void sweep_4(
  			surface_create_description *Surface_Descr,
  			std::string &sweep_fname,
  			int verbose_level);
  	void sweep_4_27(
  			surface_create_description *Surface_Descr,
  			std::string &sweep_fname,
  			int verbose_level);
  	void table_of_cubic_surfaces(int verbose_level);
  
  };
  
  
  
  }}
  
  
  
  
  #endif /* SRC_LIB_TOP_LEVEL_SURFACES_SURFACES_GENERAL_SURFACES_GENERAL_H_ */
  