From 5a5f124f6b718e0c6221caf362d5f5db53740815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ne=C4=8Dada?= Date: Tue, 25 Jun 2019 20:05:31 +0300 Subject: [PATCH] Doxygen docs for the lattice generators. Former-commit-id: eb3a5149a7f3fac70e5bf882642690ef31e1d6e4 --- Doxyfile | 2 +- qpms/lattices.h | 189 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 150 insertions(+), 41 deletions(-) diff --git a/Doxyfile b/Doxyfile index 4c723bb..49d6842 100644 --- a/Doxyfile +++ b/Doxyfile @@ -427,7 +427,7 @@ EXTRACT_PACKAGE = NO # included in the documentation. # The default value is: NO. -EXTRACT_STATIC = NO +EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined # locally in source files will be included in the documentation. If set to NO diff --git a/qpms/lattices.h b/qpms/lattices.h index 79f9f6c..d922e3e 100644 --- a/qpms/lattices.h +++ b/qpms/lattices.h @@ -1,3 +1,7 @@ +/*! \file lattices.h + * \brief Lattice point generators and lattice vector analysis / transformation. + * + */ #ifndef LATTICES_H #define LATTICES_H @@ -53,20 +57,18 @@ static inline point2d point2d_fromxy(const double x, const double y) { return p; } - - - -/* - * GENERIC LATTICE POINT GENERATOR TYPE PGen - * ============================================ - * +/// Generic lattice point generator type. +/** * A bit of OOP-in-C brainfuck here. * * The basic principle of operation is following: * Instead of a list (array) of points, an initialized PGen object * is passed to a function that does something over a set of points. - * Each time PGen-type object is "called", it returns PGenReturnData, - * which contains a point in spherical coordinates (sph_t) and some metadata. + * Each time PGen-type object is "called" (more specifically, one of + * the "methods" specified in the PGenClassInfo structure in @ref c, + * it returns PGenReturnData + * which contains a point in given coordinates (depending on the generator + * class) and some metadata. * * After the last generated point, the generator frees all internal memory * and returns PGenSphReturnData with PGEN_NOTDONE flag unset (the rest @@ -75,20 +77,52 @@ static inline point2d point2d_fromxy(const double x, const double y) { * even when the PGEN_NOTDONE was set in the last returned data. * In such case, the caller shall call PGen_destroy() manually. * - * MEMORY MANAGEMENT POLICY + * Methods + * ------- + * + * The standard wrapper "methods" to generate a single point in a given + * coordinate system are + * + * * PGen_next_z(), + * * PGen_next_cart2(), + * * PGen_next_cart3(), + * * PGen_next_pol(), + * * PGen_next_sph(). + * + * Memory management policy * ------------------------ + * * The basic PGen structure shall be allocated on stack (it's only two pointers), * everything internal goes on heap. */ - -struct PGen; // full definition below +typedef struct PGen { + /// Pointer to the "class" metadata defining the behaviour of the generator. + const struct PGenClassInfo * /*const*/ c; + /// Pointer to internal state data; shall be NULL if invalid (destroyed); + void *stateData; +} PGen; typedef enum PGenPointFlags { - PGEN_NOTDONE = 2, // The most important flag: when this is not set, the interation ended – other data returned should be considered nonsense and at this point, the generator should have de-allocated all internal memory. - PGEN_NEWR = 1, // The r-coordinate is different than in the previous generated point (so radial parts of the calculation have to be redone); - PGEN_AT_Z = 4, // This is set if we are at the z-axis (theta is either 0 or M_PI) - PGEN_AT_XY = 8, // This is set if we are at the xy-plane (theta is M_PI2) - PGEN_DONE = 0, // convenience value, not an actual flag + /** The most important flag: when this is not set, the + * interation ended – other data returned should be + * considered nonsense and at this point, the generator + * should have de-allocated all internal memory. + */ + PGEN_NOTDONE = 2, + /** Set if the r-coordinate is different than in the + * previous generated point (so radial parts of the + * calculation have to be redone). + */ + PGEN_NEWR = 1, + /** Set if the r-coordinate has changed between the + * first and the last point generated in the current + * call. + * Only for the bulk generator methods. + */ + PGEN_RCHANGED = 16, + PGEN_AT_Z = 4, ///< Set if the point(s) lie(s) at the z-axis (theta is either 0 or M_PI). + PGEN_AT_XY = 8, ///< Set if the point(s) lie(s) in the xy-plane (theta is M_PI2). + PGEN_DONE = 0, ///< Convenience identifier, not an actual flag. PGEN_COORDS_CART1 = QPMS_COORDS_CART1, PGEN_COORDS_CART2 = QPMS_COORDS_CART2, PGEN_COORDS_CART3 = QPMS_COORDS_CART3, @@ -98,34 +132,48 @@ typedef enum PGenPointFlags { PGEN_COORDS_CART2 | PGEN_COORDS_CART3 | PGEN_COORDS_POL | PGEN_COORDS_SPH } PGenPointFlags; -typedef struct PGenReturnData { // Generic return type that might contain point represented in any of the supported coordinate systems - PGenPointFlags flags; // metadata; must contain info about the coordinate system - anycoord_point_t point; + +/// Metadata generated by the fetch*() methods from PGenClassInfo +typedef struct PGenReturnDataBulk { + /// Flags describing the returned data. + PGenPointFlags flags; + size_t generated; ///< Number of points really generated +} PGenReturnDataBulk; + +/// Generic PGen return type that might contain point represented in any of the supported coordinate systems. +typedef struct PGenReturnData { + PGenPointFlags flags; ///< Metadata, must contain valid coordinate system defining flags. + anycoord_point_t point; ///< Generated point in a coordinate system defined by flags. } PGenReturnData; +/// PGen single-point return data type (1D). typedef struct PGenZReturnData { - PGenPointFlags flags; // metadata - double point_z; + PGenPointFlags flags; ///< Medatata. + double point_z; ///< Generated point on a real axis. } PGenZReturnData; +/// PGen single-point return data type (2D, polar coordinates). typedef struct PGenPolReturnData { - PGenPointFlags flags; // metadata - pol_t point_pol; + PGenPointFlags flags; ///< Metadata. + pol_t point_pol; ///< Generated point in polar coordinates. } PGenPolReturnData; +/// PGen single-point return data type (3D, spherical coordinates). typedef struct PGenSphReturnData { - PGenPointFlags flags; // metadata - sph_t point_sph; // the actual point data + PGenPointFlags flags; ///< Metadata. + sph_t point_sph; ///< Generated point in spherical coordinates. } PGenSphReturnData; +/// PGen single-point return data type (2D, cartesian coordinates). typedef struct PGenCart2ReturnData { - PGenPointFlags flags; // metadata - cart2_t point_cart2; // the actual point data + PGenPointFlags flags; ///< Metadata. + cart2_t point_cart2; ///< Generated point in cartesian coordinates. } PGenCart2ReturnData; +/// PGen single-point return data type (3D, cartesian coordinates). typedef struct PGenCart3ReturnData { - PGenPointFlags flags; // metadata - cart3_t point_cart3; // the actual point data + PGenPointFlags flags; ///< Metadata. + cart3_t point_cart3; ///< Generated point in cartesian coordinates. } PGenCart3ReturnData; // convenience constants for use in the extractor implementations @@ -135,36 +183,74 @@ static const PGenSphReturnData PGenSphDoneVal = {PGEN_DONE, {0,0,0}}; static const PGenCart2ReturnData PGenCart2DoneVal = {PGEN_DONE, {0,0}}; static const PGenCart3ReturnData PGenCart3DoneVal = {PGEN_DONE, {0,0,0}}; + +/// PGen class metadata. +/** + * This structure determines the behaviour of the PGen + * instance pointing to it. + * + * For generating a single point, use the next() method. + * For generating up to N points in a single call, use the + * fetch() method. + * + * Usually, each generator uses internally one "native" coordinate + * system (in lattice generators, this will typically be nD + * cartesian coordinates) in which the next() method gives its result. + * + * One does not have to explicitly implement every single method. + * + * TODO doc about the default transformations etc. + */ typedef struct PGenClassInfo { // static PGenSph info char * const name; // mainly for debugging purposes int dimensionality; // lower-dimensional can be converted to higher-D, not vice versa; bit redundant with the following, whatever. - PGenPointFlags native_point_flags; // info about native coordinate system + /// Info about the generator native coordinate system. + PGenPointFlags native_point_flags; + /// Generate a single point in the native coordinates. PGenReturnData (*next)(struct PGen *); + /// Generate a single 1D point. PGenZReturnData (*next_z)(struct PGen *); - PGenPolReturnData (*next_pol)(struct PGen *); // This contains the actual generator procedure (TODO shouldn't I rather point to stateData?) + /// Generate a single 2D point in polar coordinates. + PGenPolReturnData (*next_pol)(struct PGen *); + /// Generate a single 3D point in spherical coordinates. PGenSphReturnData (*next_sph)(struct PGen *); + /// Generate a single 2D point in cartesian coordinates. PGenCart2ReturnData (*next_cart2)(struct PGen *); + /// Generate a single 3D point in cartesian coordinates. PGenCart3ReturnData (*next_cart3)(struct PGen *); +#if 0 // must be implemented first. + /// Generate up to \a n points in the native coordinates. + PGenReturnDataBulk (*fetch)(struct PGen *, size_t, anycoord_point_t *); + /// Generate up to \a n 1D points. + PGenReturnDataBulk (*fetch_z)(struct PGen *, size_t, double *); + /// Generate up to \a n 2D points in polar coordinates. + PGenReturnDataBulk (*fetch_pol)(struct PGen *, size_t, pol_t *); + /// Generate up to \a n 3D points in spherical coordinates. + PGenReturnDataBulk (*fetch_sph)(struct PGen *, size_t, sph_t *); + /// Generate up to \a n 2D points in cartesian coordinates. + PGenReturnDataBulk (*fetch_cart2)(struct PGen *, size_t, cart2_t); + /// Generate up to \a n 3D points in cartesian coordinates. + PGenReturnDataBulk (*fetch_cart3)(struct PGen *, size_t, cart3_t); +#endif void (*destructor)(struct PGen *); // Destructor to be called by next() at iteration end, or by the caller if ending the generation prematurely } PGenClassInfo; -// TOP DATA STRUCTURE DEFINITION HERE -typedef struct PGen { - const PGenClassInfo * /*const*/ c; - void *stateData; // shall be NULL if invalid (destroyed) -} PGen; + +/// Deallocate and invalidate a PGen point generator. static inline void PGen_destroy(PGen *g) { g->c->destructor(g); assert(g->stateData == NULL); // this should be done by the destructor } +/// Generate a point in a 1D real space. static inline PGenZReturnData PGen_next_z(PGen *g) { if (g->c->next_z) return g->c->next_z(g); else abort(); } +/// Generate a point in a 3D real space (spherical coordinates). static inline PGenSphReturnData PGen_next_sph(PGen *g) { // TODO maybe some asserts around here if (g->c->next_sph) @@ -172,6 +258,7 @@ static inline PGenSphReturnData PGen_next_sph(PGen *g) { else abort(); // the current point generator does not support this type of output } +/// Generate a point in a 2D real space (polar coordinates). static inline PGenPolReturnData PGen_next_pol(PGen *g) { // TODO maybe some asserts around here if (g->c->next_pol) @@ -179,6 +266,7 @@ static inline PGenPolReturnData PGen_next_pol(PGen *g) { else abort(); // the current point generator does not support this type of output } +/// Generate a point in a 3D real space (cartesian coordinates). static inline PGenCart3ReturnData PGen_next_cart3(PGen *g) { // TODO maybe some asserts around here if (g->c->next_cart3) @@ -186,6 +274,7 @@ static inline PGenCart3ReturnData PGen_next_cart3(PGen *g) { else abort(); // the current point generator does not support this type of output } +/// Ǧenerate a point in a 2D real space (cartesian coordinates). static inline PGenCart2ReturnData PGen_next_cart2(PGen *g) { // TODO maybe some asserts around here if (g->c->next_cart2) @@ -193,6 +282,15 @@ static inline PGenCart2ReturnData PGen_next_cart2(PGen *g) { else abort(); // the current point generator does not support this type of output } +#if 0 +/// Generate up to \a n points. +static inline PGenReturnDataBulk PGen_fetch(PGen *g, size_t n, anycoord_point_t *arr){ + if (g->c->fetch) + return g->c->fetch(g, n, arr); + else abort(); +} +#endif + static inline bool PGenSph_notDone(PGenSphReturnData data) { return data.flags & PGEN_NOTDONE ? true : false; } @@ -200,6 +298,7 @@ static inline bool PGenCart3_notDone(PGenCart3ReturnData data) { return data.flags & PGEN_NOTDONE ? true : false; } +/// Standard PGen spherical coordinates -> 3d cartesian convertor. static inline PGenCart3ReturnData PGenReturnDataConv_sph_cart3(PGenSphReturnData sphdata){ PGenCart3ReturnData c3data; c3data.flags = sphdata.flags; @@ -207,6 +306,7 @@ static inline PGenCart3ReturnData PGenReturnDataConv_sph_cart3(PGenSphReturnData return c3data; } +/// Standard PGen 3d cartesian -> spherical coordinates convertor. static inline PGenSphReturnData PGenReturnDataConv_cart3_sph(PGenCart3ReturnData c){ PGenSphReturnData s; s.flags = c.flags; @@ -218,10 +318,12 @@ static inline PGenSphReturnData PGenReturnDataConv_cart3_sph(PGenCart3ReturnData * Some basic lattice generators implementing the abstract interface above (implemented in latticegens.c). */ -// This one simply iterates over an existing array of Point2d +/// 2D point generator that simply iterates over an existing array of Point2d. extern const PGenClassInfo PGen_FromPoint2DArray; // TODO Do I even need this to be declared here? +/// PGen_FromPoint2DArray constructor. PGen PGen_FromPoints2DArray_new(const point2d *points, size_t len); +/// 1D equidistant point generator. extern const PGenClassInfo PGen_1D; typedef enum PGen_1D_incrementDirection{ //PGEN_1D_POSITIVE_INC, // not implemented @@ -229,8 +331,15 @@ typedef enum PGen_1D_incrementDirection{ PGEN_1D_INC_FROM_ORIGIN, PGEN_1D_INC_TOWARDS_ORIGIN } PGen_1D_incrementDirection; -PGen PGen_1D_new_minMaxR(double period, double offset, double minR, bool inc_minR, double maxR, bool inc_maxR, - PGen_1D_incrementDirection incdir); +/// PGen_1D point generator constructor. +PGen PGen_1D_new_minMaxR(double period, ///< Distance between points. + double offset, ///< Lattice offset from zero. + double minR, ///< Lower bound of |z| of the generated points. + bool inc_minR, ///< Include also |z| == minR (if applicable). + double maxR, ///< Upper bound of |z| of the generated points. + bool inc_maxR, ///< Include also |z| == maxR if applicable. + PGen_1D_incrementDirection incdir ///< Order of generated points. +); extern const PGenClassInfo PGen_xyWeb;