TIN::TIN() : mMesh(NULL), mBehavior(NULL), mRecentTri(NULL), mMinZ(std::numeric_limits<double>::max()), mMaxZ(-1 * std::numeric_limits<double>::max()) { mMesh = new TMesh; mBehavior = new TBehavior; mRecentTri = new TOrientedTriangle; // Using incremental algorithm for triangulation char * switches = {"zQ"}; triangleinit(mMesh); parsecommandline(1, &switches, mBehavior); mRecentTri->tri = NULL; mRecentTri->orient = 0; }
/* This function should be called from main() to configure the program. * After the configurations have been initialized the command line is * parsed. Then the configuration file is read and after that if any * parameter has not been set the defaults are used. */ int opt_configure(int argc, const char *argv[]) { initconfig(); parsecommandline(argc, argv); if(readconfigfile()) { xerror("Unable to read configuration running with defaults"); } setdefaults(); // xlog(LOG_CONFIG, "Daemonize set to %d", _daemonize); // xlog(LOG_CONFIG, "Status Tagname is set to %s", _statustag); // xlog(LOG_CONFIG, "PID File Name set to %s", _pidfile); return 0; }
int cmd_call(char *param) { /* * Perform CALL command. * * Allocate a new batch context and add it to the current chain. * Call parsecommandline passing in our param string * If No batch file was opened then remove our newly allocted * context block. */ struct bcontext *n = newBatchContext(); int ec; if (n == 0) { /* Not in a batch file */ return 1; } optS = optN = 0; if((ec = leadOptions(¶m, opt_call, 0)) != E_None) return ec; if(swapOnExec != ERROR) { if(optS) swapOnExec = TRUE; if(optN) swapOnExec = FALSE; } parsecommandline(param, FALSE); if(swapOnExec != ERROR) swapOnExec = FALSE; if (bc->bfile == 0 && bc->bfnam == 0) { /* Wasn't a batch file so remove context */ bc = bc->prev; free(n); } return 0; }
/* * do the prompt/input/process loop * * If xflg is true, the function will not go interactive, but returns. * If commandline != NULL, this command is processed first. * * Return: 0: on success */ int process_input(int xflag, char *commandline) { /* Dimensionate parsedline that no sprintf() can overflow the buffer */ char parsedline[MAX_INTERNAL_COMMAND_SIZE + sizeof(errorlevel) * 8] , *readline; /* Return the maximum pointer into parsedline to add 'numbytes' bytes */ #define parsedMax(numbytes) \ (parsedline + MAX_INTERNAL_COMMAND_SIZE - 1 - (numbytes)) char *evar; char *tp; char *ip; char *cp; char forvar; int echothisline; int tracethisline; do { interactive_command = 0; /* not directly entered by user */ echothisline = tracethisline = 0; if(commandline) { ip = commandline; readline = commandline = NULL; } else { if ((readline = malloc(MAX_INTERNAL_COMMAND_SIZE + 1)) == NULL) { error_out_of_memory(); return 1; } if (NULL == (ip = readbatchline(&echothisline, readline, MAX_INTERNAL_COMMAND_SIZE))) { /* if no batch input then... */ if (xflag /* must not go interactive */ || (fdattr(0) & 0x84) == 0x84 /* input is NUL device */ || feof(stdin)) /* no further input */ { free(readline); break; } /* Go Interactive */ interactive_command = 1; /* directly entered by user */ readcommand(ip = readline, MAX_INTERNAL_COMMAND_SIZE); tracemode = 0; /* reset trace mode */ } } /* * The question mark '?' has a double meaning: * C:\> ? * ==> Display short help * * C:\> ? command arguments * ==> enable tracemode for just this line */ if(*(ip = trim(ip)) == '?') { ip = trim(ip + 1); if(!*ip) { /* is short help command */ #ifdef INCLUDE_CMD_QUESTION showcmds(ip); #endif free(readline); continue; } /* this-line-tracemode */ echothisline = 0; tracethisline = 1; } /* The FOR hack If the line matches /^\s*for\s+\%[a-z]\s/, the FOR hack becomes active, because FOR requires the sequence "%<ch>" in its input. When the percent (%) expansion is made later on, any sequence "%<ch>" is retained. */ cp = ip; if(matchtok(cp, "for") && *cp == '%' && isalpha(cp[1]) && isspace(cp[2])) /* activate FOR hack */ forvar = toupper(cp[1]); else forvar = 0; cp = parsedline; while (*ip) { /* Assume that at least one character is added, place the test here to simplify the switch() statement */ if(cp >= parsedMax(1)) { cp = NULL; /* error condition */ break; } if (*ip == '%') { switch (*++ip) { case '\0': /* FOR hack forvar == 0 if no FOR is active */ *cp++ = '%'; break; case '%': *cp++ = *ip++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (NULL != (tp = find_arg(*ip - '0'))) { if(cp >= parsedMax(strlen(tp))) { cp = NULL; goto intBufOver; } cp = stpcpy(cp, tp); ip++; } else *cp++ = '%'; /* Let the digit be copied in the cycle */ break; case '?': /* overflow check: parsedline has that many character "on reserve" */ cp += sprintf(cp, "%u", errorlevel); ip++; break; default: if(forvar == toupper(*ip)) { /* FOR hack */ *cp++ = '%'; /* let the var be copied in next cycle */ break; } if ((tp = strchr(ip, '%')) != NULL) { *tp = '\0'; if ((evar = getEnv(ip)) != NULL) { if(cp >= parsedMax(strlen(evar))) { cp = NULL; goto intBufOver; } cp = stpcpy(cp, evar); } ip = tp + 1; } break; } continue; } if (iscntrl(*ip)) *cp = ' '; else *cp++ = *ip++; } intBufOver: free(readline); if(!cp) { /* internal buffer overflow */ error_line_too_long(); continue; } *cp = '\0'; /* terminate copied string */ if (echothisline) /* Echo batch file line */ { printprompt(); puts(parsedline); } if (*parsedline) { if(tracethisline) ++tracemode; parsecommandline(parsedline); if(tracethisline) --tracemode; if (echothisline || echo) putchar('\n'); } } while (!canexit || !exitflag); return 0; }
int cmd_if(char *param) { #define X_EXEC 1 char *pp; int x_flag = 0; /* when set cause 'then' clause to be exec'ed */ int negate = 0; /* NOT keyword present */ int ignore_case = 0; /* /I option, case insensitive compare */ /* First check if param exists */ assert(param); /* check for options, note non-options must be treated as part of comparision */ if (matchtok(param, "/I")||matchtok(param, "/i")) ignore_case++; /* next check if param string begins with word 'not' */ if(matchtok(param, "not")) negate = X_EXEC; /* Remember 'NOT' */ /* Check for 'exist' form */ if(matchtok(param, "exist")) { struct dos_ffblk f; isr olderrhandler; if(!*param) { /* syntax error */ error_if_exist(); return 0; } pp = skip_word(param); *pp++ = '\0'; /* don't show abort/retry/fail if no disk in drive */ get_isr(0x24, olderrhandler); #ifdef XMS_SWAP set_isrfct(0x24, autofail_err_handler); /* always fails */ #else set_isrfct(0x24, dummy_criter_handler); /* always fails */ #endif if(dos_findfirst(param, &f, FA_NORMAL|FA_ARCH|FA_SYSTEM|FA_RDONLY|FA_HIDDEN) == 0) x_flag = X_EXEC; dos_findclose(&f); /* restore critical error handler */ set_isrfct(0x24, olderrhandler); } /* Check for 'errorlevel' form */ else if(matchtok(param, "errorlevel")) { int n = 0; #if 0 if(!isdigit(*param)) { error_if_errorlevel(); return 0; } pp = param; do n = n * 10 + (*pp - '0'); while (isdigit(*++pp)); if(*pp && !isargdelim(*pp)) { error_if_errorlevel_number(); return 0; } #else /* Add this COMMAND bug as someone tries to use: IF ERRORLEVEL H<upper-case_letter> -or- IF ERRORLEVEL x<lower-case_letter> to match the errorlevel against drive letters. NOT supported by 4dos or WinNT. HA --> maps to errorlevel 1 xa --> same HB & xb --> to 2 a.s.o. */ if(!*param) { error_if_errorlevel(); return 0; } pp = param; do n = n * 10 + (*pp - '0'); while(*++pp && !isargdelim(*pp)); n &= 255; dprintf( ("IF: checking for ERRORLEVEL >= %u\n", n) ); #endif if(errorlevel >= n) x_flag = X_EXEC; } /* Check that '==' is present, syntax error if not */ else { size_t len; char *r; /* right operand */ pp = skipqword(param, "=="); if(*pp != '=' || pp[1] != '=') { error_syntax(0); return 0; } *pp = '\0'; /* param[] points to the left operand */ /* skip over the '==' and subsquent spaces and assign the end of the right operator to pp */ pp = skipqword(r = ltrimcl(pp + 2), 0); /* now: param := beginning of the left operand r := beginning of the right operand pp := end of right operand */ rtrimcl(param); /* ensure that spurious whitespaces are ignored */ len = strlen(param); /* check if strings differ */ if ( ((pp - r) == len) && ((ignore_case && strnicmp(param, r, len) == 0) || (memcmp(param, r, len) == 0)) ) x_flag = X_EXEC; } if(x_flag ^ negate) /* perform the command */ if(!*(pp = ltrimcl(pp))) error_if_command(); else parsecommandline(pp, FALSE); return 0; }
// Customized triangulation call. void custom_triangulate(char *triswitches, struct triangulateio *in, struct triangulateio *out, struct triangulateio *vorout, const int *outside, const int *inside) { struct mesh m; struct behavior b; //REAL *holearray; //REAL *regionarray; triangleinit(& m); parsecommandline(1, & triswitches, & b); //b.verbose=2; m.steinerleft = b.steiner; transfernodes(& m, & b, in->pointlist, in->pointattributelist, in->pointmarkerlist, in->numberofpoints, in->numberofpointattributes); if ( b.refine ) { m.hullsize = reconstruct(& m, & b, in->trianglelist, in->triangleattributelist, in->trianglearealist, in->numberoftriangles, in->numberofcorners, in->numberoftriangleattributes, in->segmentlist, in->segmentmarkerlist, in->numberofsegments); } else { m.hullsize = delaunay(& m, & b); } m.infvertex1 = ( vertex ) NULL; m.infvertex2 = ( vertex ) NULL; m.infvertex3 = ( vertex ) NULL; if ( b.usesegments ) { m.checksegments = 1; if ( !b.refine ) { formskeleton(& m, & b, in->segmentlist, in->segmentmarkerlist, in->numberofsegments); } } #if 0 struct osub subsegloop; traversalinit(& m.subsegs); subsegloop.ss = subsegtraverse(& m); subsegloop.ssorient = 0; while ( subsegloop.ss != ( subseg * ) NULL ) { if ( subsegloop.ss != m.dummysub ) { REAL *p1, *p2; sorg(subsegloop, p1); sdest(subsegloop, p2); printf(" Connected (%f,%f) to (%f,%f)\n", p1 [ 0 ], p1 [ 1 ], p2 [ 0 ], p2 [ 1 ]); subsegloop.ss = subsegtraverse(& m); } } #endif if ( b.poly && ( m.triangles.items > 0 ) ) { //holearray = in->holelist; m.holes = in->numberofholes; //regionarray = in->regionlist; m.regions = in->numberofregions; if ( !b.refine ) { /* Only increase quality if the regions are properly defined. */ int sane = custom_carveholes(& m, & b, outside, inside); b.quality *= sane; if ( sane == 0 ) { printf("Probably bad PSLG\n"); exit(-1); } } } else { m.holes = 0; m.regions = 0; } if ( b.quality && ( m.triangles.items > 0 ) ) { enforcequality(& m, & b); } m.edges = ( 3l * m.triangles.items + m.hullsize ) / 2l; if ( b.order > 1 ) { highorder(& m, & b); } if ( !b.quiet ) { printf("\n"); } if ( b.jettison ) { out->numberofpoints = m.vertices.items - m.undeads; } else { out->numberofpoints = m.vertices.items; } out->numberofpointattributes = m.nextras; out->numberoftriangles = m.triangles.items; out->numberofcorners = ( b.order + 1 ) * ( b.order + 2 ) / 2; out->numberoftriangleattributes = m.eextras; out->numberofedges = m.edges; if ( b.usesegments ) { out->numberofsegments = m.subsegs.items; } else { out->numberofsegments = m.hullsize; } if ( vorout != ( struct triangulateio * ) NULL ) { vorout->numberofpoints = m.triangles.items; vorout->numberofpointattributes = m.nextras; vorout->numberofedges = m.edges; } if ( b.nonodewritten || ( b.noiterationnum && m.readnodefile ) ) { if ( !b.quiet ) { printf("NOT writing vertices.\n"); } numbernodes(& m, & b); } else { writenodes(& m, & b, & out->pointlist, & out->pointattributelist, & out->pointmarkerlist); } // Simp. always write the triangles. writeelements(& m, & b, & out->trianglelist, & out->triangleattributelist); if ( b.poly || b.convex ) { writepoly(& m, & b, & out->segmentlist, & out->segmentmarkerlist); out->numberofholes = m.holes; out->numberofregions = m.regions; if ( b.poly ) { out->holelist = in->holelist; out->regionlist = in->regionlist; } else { out->holelist = ( REAL * ) NULL; out->regionlist = ( REAL * ) NULL; } } if ( b.edgesout ) { writeedges(& m, & b, & out->edgelist, & out->edgemarkerlist); } // Simp. no voronoi if ( b.neighbors ) { writeneighbors(& m, & b, & out->neighborlist); } // Simp. No statistics. if ( b.docheck ) { checkmesh(& m, & b); checkdelaunay(& m, & b); } triangledeinit(& m, & b); }
int _Cdecl my2e_parsecommandline( char *s ) { s[ (unsigned char)s[ 0 ] ] = '\0'; /* printf("_my2e_parsecommandline( %s )\n", s );*/ parsecommandline( &s[ 1 ], 1 ); return( errorlevel ); }
/* * do the prompt/input/process loop * * If xflg is true, the function will not go interactive, but returns. * If commandline != NULL, this command is processed first. * * Return: 0: on success */ int process_input(int xflag, char *commandline) { /* Dimensionate parsedline that no sprintf() can overflow the buffer */ char parsedline[MAX_INTERNAL_COMMAND_SIZE + sizeof(errorlevel) * 8] , *readline; #if 0 /* Return the maximum pointer into parsedline to add 'numbytes' bytes */ #define parsedMax(numbytes) \ (parsedline + MAX_INTERNAL_COMMAND_SIZE - 1 - (numbytes)) char *evar; char *tp; char *cp; #endif char *ip; #if 0 char forvar; #endif int echothisline; int tracethisline; do { #ifdef FEATURE_LONG_FILENAMES if( toupper( *getEnv( "LFN" ) ) == 'N' ) __supportlfns = 0; else __supportlfns = 1; #endif interactive_command = 0; /* not directly entered by user */ echothisline = tracethisline = 0; if(commandline) { ip = commandline; readline = commandline = 0; } else { if ((readline = malloc(MAX_INTERNAL_COMMAND_SIZE + 1)) == 0) { error_out_of_memory(); return 1; } if (0 == (ip = readbatchline(&echothisline, readline, MAX_INTERNAL_COMMAND_SIZE))) { /* if no batch input then... */ if (xflag /* must not go interactive */ || (fdattr(0) & 0x84) == 0x84 /* input is NUL device */ || feof(stdin)) /* no further input */ { free(readline); break; } /* Go Interactive */ interactive_command = 1; /* directly entered by user */ /* Ensure the prompt starts at column #0 */ if(echo && (mywherex()>1)) outc('\n'); readcommand(ip = readline, MAX_INTERNAL_COMMAND_SIZE); tracemode = 0; /* reset trace mode */ } } /* Make sure there is no left-over from last run */ currCmdHelpScreen = 0; /* * The question mark '?' has a double meaning: * C:\> ? * ==> Display short help * * C:\> ? command arguments * ==> enable tracemode for just this line */ if(*(ip = ltrimcl(ip)) == '?') { ip = ltrimcl(ip + 1); if(!*ip) { /* is short help command */ #ifdef INCLUDE_CMD_QUESTION showcmds(ip); #endif free(readline); continue; } /* this-line-tracemode */ echothisline = 0; tracethisline = 1; } #if 0 /* The FOR hack If the line matches /^\s*for\s+\%[a-z]\s/, the FOR hack becomes active, because FOR requires the sequence "%<ch>" in its input. When the percent (%) expansion is made later on, any sequence "%<ch>" is retained. */ cp = ip; if(matchtok(cp, "for") && *cp == '%' && isalpha(cp[1]) && isargdelim(cp[2])) /* activate FOR hack */ forvar = toupper(cp[1]); else forvar = 0; #else if(cmd_for_hackery(ip)) { free(readline); continue; } #endif { int rc = expandEnvVars(ip, parsedline); free(readline); if(!rc) { error_line_too_long(); continue; } } if (echothisline) /* Echo batch file line */ { printprompt(); puts(parsedline); } if (*parsedline) { if(swapOnExec != ERROR) swapOnExec = defaultToSwap; if(tracethisline) ++tracemode; parsecommandline(parsedline, TRUE); if(tracethisline) --tracemode; } } while (!canexit || !exitflag); return 0; }
int cmd_set(char *param) { char *value; char *promptBuf = 0, tempcmd[255]; int ret; optC = promptUser = upCaseValue = optExecute = 0; if(leadOptions(¶m, opt_set, 0) != E_None) return 1; switch(breakVarAssign(ctxtEnvironment, param, &value)) { case 1: /* no equal sign */ #ifdef FEATURE_CMD_SET_PRINT if( ( value = getEnv( param ) ) != NULL ) printf( "%s\n", value ); else { error_env_var_not_found( param ); return( 1 ); } return( 0 ); #else error_syntax(0); return 1; #endif case 0: /* displayed */ return 0; #ifdef DEBUG case 2: break; default: dprintf(("[SET: Invalid response from breakVarAssign()]\n")); return 1; #endif } if(promptUser) { /* -> Display the value, then read and assign */ assert(value); fputs(value, stdout); promptBuf = malloc(promptBuffer); if(!promptBuf) { error_out_of_memory(); return E_NoMem; } fgets(promptBuf, promptBuffer, stdin); if(cbreak) { free(promptBuf); return E_CBreak; } value = strchr(promptBuf, '\0'); while(--value >= promptBuf && (*value == '\n' || *value == '\r')); value[1] = '\0'; /* strip trailing newlines */ value = promptBuf; } if (optExecute) { char *tempfile = tmpfn(); FILE *fhandle; if (!tempfile) return (1); sprintf (tempcmd, "%s>%s", value, tempfile); parsecommandline (tempcmd, TRUE); fhandle = fopen (tempfile, "r"); if (!fhandle) { unlink (tempfile); free (tempfile); return (1); } fgets (tempcmd, 255, fhandle); value = strchr(tempcmd, '\n'); if (value) *value = '\0'; value = tempcmd; fclose (fhandle); unlink (tempfile); free (tempfile); } /* If the value is just blanks, it means to delete the value; but otherwise even leading and trailing spaces must be kept */ if(is_empty(value)) value = 0; if (upCaseValue) StrUpr(value); /* set value as upper case, eg for if testing */ ret = chgEnvCase(optC, param, value); free(promptBuf); return ret; }
int main (int argc, char * argv[]) { // Plant frequencies... (zeroed here just to suppress a -Wall warning) float f_AA_MM = 0; float f_AA_Mm = 0; float f_AA_mm = 0; float f_Aa_MM = 0; float f_Aa_Mm = 0; float f_Aa_mm = 0; float f_aa_MM = 0; float f_aa_Mm = 0; float f_aa_mm = 0; float next_f_AA_MM; float next_f_AA_Mm; float next_f_AA_mm; float next_f_Aa_MM; float next_f_Aa_Mm; float next_f_Aa_mm; float next_f_aa_MM; float next_f_aa_Mm; float next_f_aa_mm; // Pollen frequencies... float p_A_M; float p_A_m; float p_a_M; float p_a_m; // Egg frequencies... float e_A_M; float e_A_m; float e_a_M; float e_a_m; float male = 0; float female = 0; float inconstant = 0; float PSatC; // Pollen saturation point for cosex receivers float K; float k; float totalpollen; float totalplants; int n; int x; int y; char bmp_filename[1024]; char txt_filename[1024]; FILE * textfile = NULL; parsecommandline(argc, argv); result = malloc(subdivisions * sizeof(int*)); if (result == NULL) { printf("Out of memory!\n"); exit(1); } for (n = 0; n < subdivisions; n++) { result[n] = malloc(subdivisions * sizeof(int)); if (result[n] == NULL) { printf("Out of memory!\n"); exit(1); } } // Print all settings... printf("\nModel %d\n\n", MODEL); if (onerun) { printf("Q = %G (K = %G, pi = %G)\n", Q, (1 / Q) - 1, 1 / Q); printf("F = %G (k = %G, \"omega\" = %G)\n\n", F, (1 / F) - 1, 1 / F); } printf("h = %G\n", h); printf("Selfing rate = %G\n", S); printf("Inbreeding depression = %G\n", d); printf("YY viability = %G (YY penalty = %G)\n", V, 1 - V); printf("PSatF = %G\n\n", PSatF); printf("Iterations = %d\n\n", endpoint); if (onerun == 0) { printf("Warning: --onerun option not received, therefore program will\n"); printf("use %d Q and F combinations and produce a graph. This may\n", subdivisions * subdivisions); printf("take a long time. If this was not your intention, terminate now.\n\n"); printf(" %d |\n", oldformat ? oldformatlimit : 1); printf("Output format: %s |\n", oldformat ? "k" : "F"); printf(" 0 |\n"); printf(" -----\n"); printf(" 0 %d\n", oldformat ? oldformatlimit : 1); printf(" %s\n\n", oldformat ? "K" : "Q"); } // Choose names for .bmp and .txt output files (if needed)... sprintf(bmp_filename, "model%d_start%s_V%G_S%G_d%G_h%G_PSatF%G_ppY%G.bmp", MODEL, pgd ? "PGD" : "DIO", V, S, d, h, PSatF, ppY); sprintf(txt_filename, "model%d_start%s_V%G_S%G_d%G_h%G_PSatF%G_ppY%G.txt", MODEL, pgd ? "PGD" : "DIO", V, S, d, h, PSatF, ppY); // Open .txt output file (if needed)... if (onerun == 0 && gnuplot) { textfile = fopen(txt_filename, "w"); } for (y = 0; y < subdivisions; y++) { for (x = 0; x < subdivisions; x++) { if (onerun == 0) { // Here we map the X,Y coordinates of our output .bmp file onto Q and F parameters... if (oldformat == 0) { Q = (float) x / (subdivisions - 1); // X axis: Q values 0 to 1 F = (float) y / (subdivisions - 1); // Y axis: F values 0 to 1 } else { K = ((float) x / (subdivisions - 1)) * oldformatlimit; // X axis: K values 0 to oldformatlimit k = ((float) y / (subdivisions - 1)) * oldformatlimit; // Y axis: k values 0 to oldformatlimit // But Q and F are the parameters actually used by the code, so calculate them: Q = 1 / (1 + K); F = 1 / (1 + k); } } // Set start plant frequencies... if (pgd == 0) // Start with DIOECY, try inconstant invasion { f_AA_MM = 0; f_AA_Mm = 0; f_AA_mm = 0.499; f_Aa_MM = 0; f_Aa_Mm = 0.002; f_Aa_mm = 0.499; f_aa_MM = 0; f_aa_Mm = 0; f_aa_mm = 0; } else { // Start with PSEUDO-GYNODIOECY, try male invasion f_AA_MM = 0.499; f_AA_Mm = 0; f_AA_mm = 0; f_Aa_MM = 0.499; f_Aa_Mm = 0; f_Aa_mm = 0.002; f_aa_MM = 0; f_aa_Mm = 0; f_aa_mm = 0; } for (n = 0; n < endpoint; n++) { // Outcrossed pollen frequencies.................................................... // // Here we sum up the 4 types of pollen (containing the 4 possible allele combinations) // from the various possible sources. We could do this in 4 equations (as in the paper) // but it's simpler to consider each source in turn and add to the totals. p_A_M = 0; p_A_m = 0; p_a_M = 0; p_a_m = 0; // From AA MM pure females (genotype 1) ; // From AA Mm pure females (genotype 2) ; // From AA mm pure females (genotype 3) ; // From Aa MM inconstants (genotype 4) as cosexes p_A_M += f_Aa_MM * 0.5 * h * Q; p_a_M += f_Aa_MM * 0.5 * h * Q; // From Aa MM inconstants (genotype 4) as males p_A_M += f_Aa_MM * 0.5 * (1 - h); p_a_M += f_Aa_MM * 0.5 * (1 - h); // From Aa Mm inconstants (genotype 5) as cosexes p_A_M += f_Aa_Mm * 0.25 * h * Q; p_A_m += f_Aa_Mm * 0.25 * h * Q; p_a_M += f_Aa_Mm * 0.25 * h * Q; p_a_m += f_Aa_Mm * 0.25 * h * Q; // From Aa Mm inconstants (genotype 5) as males p_A_M += f_Aa_Mm * 0.25 * (1 - h); p_A_m += f_Aa_Mm * 0.25 * (1 - h); p_a_M += f_Aa_Mm * 0.25 * (1 - h); p_a_m += f_Aa_Mm * 0.25 * (1 - h); // From Aa mm pure males (genotype 6) p_A_m += f_Aa_mm * 0.5; p_a_m += f_Aa_mm * 0.5; // From aa MM inconstants (genotype 7) as cosexes p_a_M += f_aa_MM * h * Q; // From aa MM inconstants (genotype 7) as males p_a_M += f_aa_MM * (1 - h); // From aa Mm inconstants (genotype 8) as cosexes p_a_M += f_aa_Mm * 0.5 * h * Q; p_a_m += f_aa_Mm * 0.5 * h * Q; // From aa Mm inconstants (genotype 8) as males p_a_M += f_aa_Mm * 0.5 * (1 - h); p_a_m += f_aa_Mm * 0.5 * (1 - h); // From aa mm pure males (genotype 9) p_a_m += f_aa_mm; // Normalise pollen frequencies to add up to 1...................................... totalpollen = p_A_M + p_A_m + p_a_M + p_a_m; if (totalpollen > 0) { p_A_M /= totalpollen; p_A_m /= totalpollen; p_a_M /= totalpollen; p_a_m /= totalpollen; } // Outcrossed egg frequencies....................................................... // Calculate pollen required to fertilise a cosex's outcrossing ovules: PSatC = PSatF * F * (1 - S); e_A_M = 0; e_A_m = 0; e_a_M = 0; e_a_m = 0; // From AA MM pure females (genotype 1) if (totalpollen >= PSatF) { e_A_M += f_AA_MM; } else { e_A_M += f_AA_MM * totalpollen / PSatF; } // From AA Mm pure females (genotype 2) if (totalpollen >= PSatF) { e_A_M += f_AA_Mm * 0.5; e_A_m += f_AA_Mm * 0.5; } else { e_A_M += f_AA_Mm * 0.5 * totalpollen / PSatF; e_A_m += f_AA_Mm * 0.5 * totalpollen / PSatF; } // From AA mm pure females (genotype 3) if (totalpollen >= PSatF) { e_A_m += f_AA_mm; } else { e_A_m += f_AA_mm * totalpollen / PSatF; } // From Aa MM inconstants (genotype 4) as cosexes if (totalpollen >= PSatC) { e_A_M += f_Aa_MM * h * 0.5 * (1 - S) * F; e_a_M += f_Aa_MM * h * 0.5 * (1 - S) * F; } else { e_A_M += f_Aa_MM * h * 0.5 * (1 - S) * F * totalpollen / PSatC; e_a_M += f_Aa_MM * h * 0.5 * (1 - S) * F * totalpollen / PSatC; } // From Aa Mm inconstants (genotype 5) as cosexes if (totalpollen >= PSatC) { e_A_M += f_Aa_Mm * h * 0.25 * (1 - S) * F; e_A_m += f_Aa_Mm * h * 0.25 * (1 - S) * F; e_a_M += f_Aa_Mm * h * 0.25 * (1 - S) * F; e_a_m += f_Aa_Mm * h * 0.25 * (1 - S) * F; } else { e_A_M += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC; e_A_m += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC; e_a_M += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC; e_a_m += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC; } // From Aa mm pure males (genotype 6) ; // From aa MM inconstants (genotype 7) as cosexes if (totalpollen >= PSatC) { e_a_M += f_aa_MM * h * (1 - S) * F; } else { e_a_M += f_aa_MM * h * (1 - S) * F * totalpollen / PSatC; } // From aa Mm inconstants (genotype 8) as cosexes if (totalpollen >= PSatC) { e_a_M += f_aa_Mm * h * 0.5 * (1 - S) * F; e_a_m += f_aa_Mm * h * 0.5 * (1 - S) * F; } else { e_a_M += f_aa_Mm * h * 0.5 * (1 - S) * F * totalpollen / PSatC; e_a_m += f_aa_Mm * h * 0.5 * (1 - S) * F * totalpollen / PSatC; } // From aa mm pure males (genotype 9) ; // WE CANNOT AND MUST NOT NORMALISE THE EGG FREQUENCIES, AS WE HAVEN'T // YET CONSIDERED THE SELFED EGGS. BUT WE DON'T NEED TO NORMALISE. // Plant frequencies from outcrossing............................................... next_f_AA_MM = p_A_M * e_A_M; next_f_AA_Mm = p_A_M * e_A_m + p_A_m * e_A_M; next_f_AA_mm = p_A_m * e_A_m; next_f_Aa_MM = p_A_M * e_a_M + p_a_M * e_A_M; next_f_Aa_Mm = p_A_M * e_a_m + p_A_m * e_a_M + p_a_M * e_A_m + p_a_m * e_A_M; next_f_Aa_mm = p_A_m * e_a_m + p_a_m * e_A_m; next_f_aa_MM = p_a_M * e_a_M; next_f_aa_Mm = p_a_M * e_a_m + p_a_m * e_a_M; next_f_aa_mm = p_a_m * e_a_m; // Additional plants from selfing................................................... // From AA MM pure females (genotype 1) ; // From AA Mm pure females (genotype 2) ; // From AA mm pure females (genotype 3) ; // From Aa MM inconstants (genotype 4) next_f_AA_MM += f_Aa_MM * 0.25 * S * (1 - d) * h * F; next_f_Aa_MM += f_Aa_MM * 0.5 * S * (1 - d) * h * F; next_f_aa_MM += f_Aa_MM * 0.25 * S * (1 - d) * h * F; // From Aa Mm inconstants (genotype 5) next_f_AA_MM += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F; next_f_AA_Mm += f_Aa_Mm * 0.125 * S * (1 - d) * h * F; next_f_AA_mm += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F; next_f_Aa_MM += f_Aa_Mm * 0.125 * S * (1 - d) * h * F; next_f_Aa_Mm += f_Aa_Mm * 0.25 * S * (1 - d) * h * F; next_f_Aa_mm += f_Aa_Mm * 0.125 * S * (1 - d) * h * F; next_f_aa_MM += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F; next_f_aa_Mm += f_Aa_Mm * 0.125 * S * (1 - d) * h * F; next_f_aa_mm += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F; // From Aa mm pure males (genotype 6) ; // From aa MM inconstants (genotype 7) next_f_aa_MM += f_aa_MM * S * (1 - d) * h * F; // From aa Mm inconstants (genotype 8) next_f_aa_MM += f_aa_Mm * 0.25 * S * (1 - d) * h * F; next_f_aa_Mm += f_aa_Mm * 0.5 * S * (1 - d) * h * F; next_f_aa_mm += f_aa_Mm * 0.25 * S * (1 - d) * h * F; // From aa mm pure males (genotype 9) ; // Apply YY penalty................................................................. next_f_aa_MM *= V; next_f_aa_Mm *= V; next_f_aa_mm *= V; // Copy............................................................................. f_AA_MM = next_f_AA_MM; f_AA_Mm = next_f_AA_Mm; f_AA_mm = next_f_AA_mm; f_Aa_MM = next_f_Aa_MM; f_Aa_Mm = next_f_Aa_Mm; f_Aa_mm = next_f_Aa_mm; f_aa_MM = next_f_aa_MM; f_aa_Mm = next_f_aa_Mm; f_aa_mm = next_f_aa_mm; // Normalise plant frequencies to add up to 1....................................... totalplants = f_AA_MM + f_AA_Mm + f_AA_mm + f_Aa_MM + f_Aa_Mm + f_Aa_mm + f_aa_MM + f_aa_Mm + f_aa_mm; if (totalplants > 0) { f_AA_MM /= totalplants; f_AA_Mm /= totalplants; f_AA_mm /= totalplants; f_Aa_MM /= totalplants; f_Aa_Mm /= totalplants; f_Aa_mm /= totalplants; f_aa_MM /= totalplants; f_aa_Mm /= totalplants; f_aa_mm /= totalplants; } } // Calculate and save results... female = f_AA_MM + f_AA_Mm + f_AA_mm; male = f_Aa_mm + f_aa_mm; inconstant = f_Aa_MM + f_Aa_Mm + f_aa_MM + f_aa_Mm; if (male > threshold && female > threshold && inconstant > threshold) { result[x][y] = SSD; } else if (male > threshold && female > threshold) { result[x][y] = DIO; } else if (female > threshold && inconstant > threshold) { result[x][y] = PGD; } else if (male > threshold && inconstant > threshold) { result[x][y] = PAD; } else if (inconstant > threshold) { result[x][y] = INC; } else { result[x][y] = 0; } if (onerun == 0 && gnuplot) { fprintf(textfile, "%f", female); if (x == subdivisions - 1) { fprintf(textfile, "\n"); } else { fprintf(textfile, "\t"); } } if (onerun) break; } if (onerun) break; } if (onerun == 0) { drawbmp(bmp_filename, 1); printf("Saved %s\n", bmp_filename); } else { printf("Females Males Inconstants\n"); printf("%.6f %.6f %.6f\n\n", female, male, inconstant); printf("Genotype frequencies, as notated by E&B (2007), or C&C (2012):\n\n"); printf("E&B: AA MM AA Mm AA mm Aa MM Aa Mm Aa mm aa MM aa Mm aa mm\n"); printf("C&C: mm AA mm Aa mm aa Mm AA Mm Aa Mm aa MM AA MM Aa MM aa\n"); printf(" %.6f %.6f %.6f %.6f %.6f %.6f %.6f %.6f %.6f\n\n", f_AA_MM, f_AA_Mm, f_AA_mm, f_Aa_MM, f_Aa_Mm, f_Aa_mm, f_aa_MM, f_aa_Mm, f_aa_mm); if (male > threshold && female > threshold && inconstant > threshold) { printf("Final state: SSD\n"); } else if (male > threshold && female > threshold) { printf("Final state: DIO\n"); } else if (female > threshold && inconstant > threshold) { printf("Final state: PGD\n"); } else if (male > threshold && inconstant > threshold) { printf("Final state: PAD\n"); } else if (inconstant > threshold) { printf("Final state: INC\n"); } else { printf("Final state: ???\n"); } } return 0; }