/*
 * Title: indequ.h
 * Author: Jed Marti KI7NNP
 * Description: Inductor equation optimization.
 * Revision History: (Created Tue Jan 24 06:51:20 2023)
 *   Sun Jan 29 12:26:51 2023 - Version 3. Better multi-process.
 *   Wed Feb  1 07:51:12 2023 - Version 5. Save tested values but only in master proc.
 *   Wed Feb  1 16:44:03 2023 - Version 6. Remove radius form denominator.
 *   Fri Feb  3 08:32:20 2023 - Version 7. Remove wire size.
 *   Tue Feb  7 14:22:53 2023 - Version 10. Remove c, make it u0.
 *   Wed Feb 15 07:01:00 2023 - Version 11. Add hash search to symbol table.
 *   Sun Feb 26 19:04:29 2023 - Version 12. Add wire size back in.
 *   Mon Feb 27 07:07:37 2023 - Version 13. Back to cubic equations.
 *   Wed Oct 11 20:05:49 2023 - Version 14. No wire size.
 *   Thu Oct 12 11:15:43 2023 - Version 15. Add 2nd order d to base.
 *   Fri Nov 24 06:36:00 2023 - Version 17. Yet another equation, no length
 *   Sun Nov 26 09:41:46 2023 - Version 19. Only cubed terms, better termination.
 *   Sun Dec  3 11:41:17 2023 - Version 20. Equation by Makefile
 */


#ifndef indequ_h
#define indequ_h

#define VERSION 20
#define RELEASE 3
#define PATCH   5

#define ASSERT(x) \
  if (!(x)) { fprintf(stderr, "%s (%s:%d) should never happen\n", __FILE__, __func__, __LINE__); \
    exit(-1); }


// Permeability of free space (fixed 20.3.3)
#define u0 1.256637061435916e-06

// Measured inductances and their mean or median values. See ../perm/*.csv for details.
typedef struct {
  void    *next;                 // For lists.
  double  L;                     // Measured inductance (mean) henries.
  double  R;                     // Radius in meters.
  double  W;                     // Wire Radius in meters.
  int32_t G;                     // Wire gauge.
  double  LEN;                   // Length in meters.
  int32_t N;                     // Number of turns.
  char    *FN;                   // File name.
  double  goodness;              // For sorting at end.
  double  computed;              // The computed inductance.
} anInductor;


// Ranges of all equation parameters.
// Must lie between [low .. high]
//   major is a low resolution
//   minor is a high resolution value.
typedef struct {
  char    *name;                 // Parameter name.
  double  low;                   // low value.
  double  high;                  // high value.
  double  major;                 // Major resolution.
  int32_t vcount;                // The number of values (computed) in major.
  double  minor;                 // Minor resolution.
  int32_t mcount;                // Number to test.
} range;

// Types for the symbol table of constant values below. 
enum {
  DESC_INT,
  DESC_DOUBLE,
  DESC_LONGINT,
  DESC_STRING
};


// Symbol table for constants from the control file.
typedef struct {
  char    *name;                // Name (case insensitive).
  union {                       // Can be one of 3 values.
    int32_t  iv;                   // Integer.
    double   dv;                   // Double
    int64_t  lv;                   // Long it.
    char     *sv;                  // Character string.
  } value;
  uint8_t descriptor;           // Type descriptor.
} symtab;


// Indices of popular values in the symbol table. These need to be in the same order as the values
// in symtab.c.
enum {
  s_population = 0,
  s_save = 1,
  s_maxgens = 2,
  s_resultf = 3,
  s_processes = 4,
  s_seed = 5,
  s_noise = 6,
  s_minormax = 7,
  s_randminor = 8,
  s_tries = 9,
  s_resultc = 10,
  s_cvarname = 11,
  s_pctchange = 12,
  s_raiselower = 13,
  s_quitat = 14,
  s_rangeexpand = 15,
  s_direction = 16,
  s_resultja = 17,
  s_javarname = 18,
  // The bese values.
#define X(nme)  s_best##nme,
  VARS
#undef X
};

// lookup.
#define isNoisy(lvl) (S[s_noise].value.iv > (lvl))


// Process control.
enum {
      idle,
      busy
};


// The process table.
typedef struct {
  char     *ifname;               // When present, means a  result to test.
  char     *rmifname;             // How to remove the file.
  char     *fname;                // The result file goes here.
  char     *rmfname;              // How to remove the result file.
  double   startTime;             // The start time.
  uint8_t  status;
} procDetail;


// Size of hash table for results. Some 32 million here.
#define HTABLESIZE (1 << 25)


////////////////////////////////////////////////////////////////////////////////////////////////////
// breed.c
result *breed(result *a, result *b, double pct);
result *mutate(result *a, double pct);
result *goodDir(result *a, double pct);

// coils.c
void showInductorResults(result *r);
void saveTempResults(result *r);

// See evaluate.c
#define NORESULT 1.0E208
double evalInductorAbs(anInductor *l, result *r);
void evalInductors(anInductor *l, result *r);
void showResult(FILE *fh, result *r);

// See geneticproc.c
result *runMajor(anInductor *l, result *r);
void optimizeProc(void);

// See genrand.c
void init_genrand64(uint64_t s);
double genUniform(range *r);
result *genRandResult(void);

// See kbhit.c
uint8_t kbhit(void);

// See library.c
void initLibrary(void);
uint8_t doneAlready(result *r);

// See process.c
void initProcs(void);
uint8_t hasFinished(int32_t proc);
void terminateProcesses(void);

// See readind.c
void readTestInductors(char *fname);

// See sort.c
result *sortgen(result *l, result *n);

// See symtab.c
void fixOneRange(result *r);
void dumpSymtab(char *msg);
void dumpRangeTable(FILE *fh, char *msg);
void checkRangeTable(void);
void readSymtab(char *fname);

// See storage.c
anInductor *newInductor(void);
result *newResult(void);
void  copyResult(result *to, result *from);
result *cloneResult(result *r);
void freeResult(result *r);
void writeResult(result *r, FILE *fh);
result *readResult(FILE *fh);

// See time.c
double timeus(void);

// See twister.c
void init_genrand64(uint64_t seed);
uint64_t genrand64_int64(void);
double uniform(void);

#endif


// EOF
