/* Compile a regular expression */ void re_compile(regex_t *preg, const char *regex, int cflags, regmatch_t **pmatch) { int i, l; char *p; static char const procname[] = "re_compile"; if (preg->re_nsub) return; /* already compiled */ if (debug) fprintf(stderr, "DEBUG: %s '%s'", procname, regex); if ((i = regcomp(preg, regex, cflags))) { l = regerror(i, preg, NULL, 0); ++l; /* doc is ambiguous, be safe */ p = malloc(l); if (!p) malloc_error("regerror text"); regerror(i, preg, p, l); fprintf(stderr, "%s: fatal %s error on '%s' - %s\n", prefix, procname, regex, p); exit(2); } if (debug) fprintf(stderr, " %d sub expression(s)\n", preg->re_nsub); /* [0] is entire match, [1] is first substring */ *pmatch = malloc((preg->re_nsub+1)*sizeof(**pmatch)); if (!*pmatch) malloc_error("pmatch"); }
t_linked_list *normalize_indentation(t_linked_list *resolved_layer, t_linked_list **strings) { int i; int x; int y; t_linked_list *tmp_line; t_linked_list *normalized; t_linked_list *tmp_normalized; t_linked_list *new_strings; t_linked_list *tmp_strings; char char_nb; char *tmp_char; new_strings = new_list(); normalized = new_list(); char_nb = 0; i = 0; while (i < resolved_layer->len) { tmp_normalized = new_list(); tmp_strings = new_list(); tmp_line = ((t_linked_list*)resolved_layer->elts[i]); x = 0; while (x < tmp_line->len && (*((char*)tmp_line->elts[x]) == TAB || *((char*)tmp_line->elts[x]) == SPACE)) x++; if (x != 0 && char_nb == 0) char_nb = x; y = 0; while (char_nb > 0 && y < x / char_nb) { if (!(tmp_char = (char*)malloc(sizeof(char)))) malloc_error(); *tmp_char = INDENT; add_to_list(tmp_normalized, tmp_char); add_to_list(tmp_strings, ft_strdup("\t")); y++; } while (x < tmp_line->len) { if (!(tmp_char = (char*)malloc(sizeof(char)))) malloc_error(); *tmp_char = *((char*)tmp_line->elts[x]); add_to_list(tmp_normalized, tmp_char); add_to_list(tmp_strings, ((char*)((t_linked_list*)(*strings)->elts[i])->elts[x])); x++; } add_to_list(normalized, tmp_normalized); add_to_list(new_strings, tmp_strings); i++; } *strings = new_strings; return (normalized); }
static int eval_mm_check(Type *impl, trace_t *trace, int tracenum) { int i, index, size, newsize; char *p, *newp, *oldp, *block; /* Reset the heap and initialize the mm package */ mem_reset_brk(); if (impl->init() < 0) { malloc_error(tracenum, 0, "impl init failed."); } /* Interpret each trace request */ for (i = 0; i < trace->num_ops; i++) { switch (trace->ops[i].type) { case ALLOC: /* malloc */ index = trace->ops[i].index; size = trace->ops[i].size; if ((p = (char *) impl->malloc(size)) == NULL) { malloc_error(tracenum, i, "impl malloc failed."); return 0; } trace->blocks[index] = p; break; case REALLOC: /* realloc */ index = trace->ops[i].index; newsize = trace->ops[i].size; oldp = trace->blocks[index]; if ((newp = (char *) impl->realloc(oldp,newsize)) == NULL) { malloc_error(tracenum, i, "impl realloc failed."); return 0; } trace->blocks[index] = newp; break; case FREE: /* free */ index = trace->ops[i].index; block = trace->blocks[index]; impl->free(block); break; default: app_error("Nonexistent request type in eval_mm_speed"); } if (impl->check() < 0) { malloc_error(tracenum, i, "impl check failed."); return 0; } } return 1; }
/* * add_range - As directed by request opnum in trace tracenum, * we've just called the student's mm_malloc to allocate a block of * size bytes at addr lo. After checking the block for correctness, * we create a range struct for this block and add it to the range list. */ static int add_range(range_t **ranges, char *lo, int size, int tracenum, int opnum) { char *hi = lo + size - 1; range_t *p; char msg[MAXLINE]; assert(size > 0); /* Payload addresses must be ALIGNMENT-byte aligned */ if (!IS_ALIGNED(lo)) { sprintf(msg, "Payload address (%p) not aligned to %d bytes", lo, ALIGNMENT); malloc_error(tracenum, opnum, msg); return 0; } /* The payload must lie within the extent of the heap */ if ((lo < (char *)mem_heap_lo()) || (lo > (char *)mem_heap_hi()) || (hi < (char *)mem_heap_lo()) || (hi > (char *)mem_heap_hi())) { sprintf(msg, "Payload (%p:%p) lies outside heap (%p:%p)", lo, hi, mem_heap_lo(), mem_heap_hi()); malloc_error(tracenum, opnum, msg); return 0; } /* The payload must not overlap any other payloads */ for (p = *ranges; p != NULL; p = p->next) { if ((lo >= p->lo && lo <= p-> hi) || (hi >= p->lo && hi <= p->hi)) { sprintf(msg, "Payload (%p:%p) overlaps another payload (%p:%p)\n", lo, hi, p->lo, p->hi); malloc_error(tracenum, opnum, msg); return 0; } } /* * Everything looks OK, so remember the extent of this block * by creating a range struct and adding it the range list. */ if ((p = (range_t *)malloc(sizeof(range_t))) == NULL) unix_error("malloc error in add_range"); p->next = *ranges; p->lo = lo; p->hi = hi; *ranges = p; return 1; }
t_vector3 *rec_vec(char *str) { int i; t_vector3 *res; i = 0; if (!(res = (t_vector3 *)malloc(sizeof(t_vector3)))) malloc_error(); while (str[i] != '"') i++; i++; res->x = ft_atoi(&str[i]); while (str[i] != '"') i++; i++; while (str[i] != '"') i++; i++; res->y = ft_atoi(&str[i]); while (str[i] != '"') i++; i++; while (str[i] != '"') i++; i++; res->z = ft_atoi(&str[i]); return (res); }
void rec_cam(int fd, char *ret, t_env *e) { if(!(e->cam = (t_cam *)malloc(sizeof(t_cam)))) malloc_error(); while (get_next_line(fd, &ret)) { if (xml_cmp(ret, "<crd") == 0) { e->cam->crd = rec_vec(ret); } if (xml_cmp(ret, "<rotation") == 0) { e->cam->rx[0] = 0; e->cam->rx[1] = 0; e->cam->rx[2] = 0; e->cam->ry[0] = 0; e->cam->ry[1] = 0; e->cam->ry[2] = 0; e->cam->rz[0] = 0; e->cam->rz[1] = 0; e->cam->rz[2] = 0; } if (xml_cmp(ret, "</camera") == 0) break; } }
/* * INITIALIZE THE SLOTS IN COMPUTER MEMORY FOR LOAD/SAVE ACTIONS * throws calloc errors */ void initializeSlots() { int slotNum, i; char fileNumber[3]={0};/*file number in string form - slot number file stored here*/ /* an array representing the slots*/ file_slots = (Slot*)calloc(sizeof(Slot),SLOT_NUM); if(file_slots==NULL){standart_fail=true; malloc_error(); return;} for(i=0 ; i < SLOT_NUM ; i++) { slotNum=i+1; /*saving the number as a string to the buffer fileNumber */ if((slotNum)/10==1){ fileNumber[0]='1'; fileNumber[1]=((slotNum)%10)+'0'; fileNumber[2]='\0'; } else{ fileNumber[0]=((slotNum)%10)+'0'; fileNumber[1]='\0'; } /* file name is : chess1.xml chess(slot number).xml */ file_slots[i].name = (char*)calloc(sizeof(char),12); if(file_slots[i].name==NULL){ calloc_error(); standart_fail=1; deleteSlots(i-1); /* delete all the slots we created so far*/ return; } strcpy(file_slots[i].name,"chess"); strcat(file_slots[i].name, fileNumber);/* file name insertion*/ strcat(file_slots[i].name,".xml"); file_slots[i].isFree = FileExists(file_slots[i].name); } }
char *fgetl(FILE *fp) { if(feof(fp)) return 0; size_t size = 512; char *line = malloc(size*sizeof(char)); if(!fgets(line, size, fp)){ free(line); return 0; } size_t curr = strlen(line); while((line[curr-1] != '\n') && !feof(fp)){ if(curr == size-1){ size *= 2; line = realloc(line, size*sizeof(char)); if(!line) { printf("%ld\n", size); malloc_error(); } } size_t readsize = size-curr; if(readsize > INT_MAX) readsize = INT_MAX-1; fgets(&line[curr], readsize, fp); curr = strlen(line); } if(line[curr-1] == '\n') line[curr-1] = '\0'; return line; }
/* ---------------------------------------------------------------------- */ void copy_defaults (struct defaults *dest_ptr, struct defaults *src_ptr) /* ---------------------------------------------------------------------- */ { int i; dest_ptr->count_iso = src_ptr->count_iso; dest_ptr->density = src_ptr->density; dest_ptr->iso = (struct iso *) PHRQ_malloc (sizeof (struct iso) * src_ptr->count_iso); if (dest_ptr->iso == NULL) { malloc_error (); } else { for (i = 0; i < src_ptr->count_iso; i++) { dest_ptr->iso[i] = src_ptr->iso[i]; dest_ptr->iso[i].name = string_duplicate (src_ptr->iso[i].name); } } dest_ptr->pe = src_ptr->pe; dest_ptr->ph = src_ptr->ph; dest_ptr->redox = string_duplicate (src_ptr->redox); dest_ptr->temp = src_ptr->temp; dest_ptr->units = string_duplicate (src_ptr->units); dest_ptr->water = src_ptr->water; }
/* ** 读取文件中的某一行,通用(仅读取一行,其读取的结果中不再有换行符或者eof,这两个符号在返回之前被处理掉了) ** 输入: *fp 打开的文件流指针 ** 输出: 读到的整行字符,返回C风格字符数组指针(最大512字节),如果读取失败,返回0 */ char *fgetl(FILE *fp) { if(feof(fp)) return 0; // 默认一行的字符数目最大为512,如果不够,下面会有应对方法 size_t size = 512; // 动态分配整行的内存:C风格字符数组 char *line = malloc(size*sizeof(char)); // char* fgets(char * str, int num, FILE *stream):从stream中读取一行数据存储到str中,最大字符数为num // fgets()函数读取数据时会以新行或者文件终止符为断点,也就是遇到新行会停止继续读入,遇到文件终止符号也会停止读入 // 注意终止符(换行符号以及eof)也会存储到str中。如果数据读取失败,返回空指针。 if(!fgets(line, size, fp)){ free(line); return 0; } // size_t strlen ( const char * str );返回C风格字符串(C String)即字符数组str的长度 // (也就是数组中存储的元素个数,不包括C字符数组最后的终止空字符,每记错的话是'\0', terminating null-character) size_t curr = strlen(line); // 终止符(换行符号以及eof)也会存储到str中,所以可用作while终止条件 // 如果一整行数据顺利读入到line中,那么line[curr-1]应该会是换行符或者eof, // 这样就可以绕过while循环中的处理;否则说明这行数据未读完,line空间不够,需要重新分配,重新读取 while((line[curr-1] != '\n') && !feof(fp)){ // 这个if语句略显多余,感觉不可能会出现curr!=size-1的情况, // 因为文件流没有问题(否则进入这个函数就返回了),那就肯定是line空间不够, // 才导致line的最后一个有效存储元素不是换行符或者eof if(curr == size-1){ // line空间不够,扩容两倍 size *= 2; // void* realloc (void* ptr, size_t size);重新动态分配大小:扩容两倍 line = realloc(line, size*sizeof(char)); // 如果动态分配内存失败,就会返回空指针,注意防护 if(!line) { printf("%ld\n", size); malloc_error(); } } // 之前因为line空间不够,没有读完一整行,此处不是从头开始读, // 而是接着往下读,并接着往下存(fgets会记着上一次停止读数据的地方) size_t readsize = size-curr; if(readsize > INT_MAX) readsize = INT_MAX-1; fgets(&line[curr], readsize, fp); curr = strlen(line); } // 实际上'\n'并不是我们想要的有效字符,因此,将其置为'\0', // 这样便于以后的处理。'\0'是C风格字符数组的terminating null-character, // 识别C字符数组时,以此为终点(不包括此字符) if(line[curr-1] == '\n') line[curr-1] = '\0'; return line; }
/* * init. the fs meta data, return the block size bits. */ static int ext2_fs_init(struct fs_info *fs) { struct disk *disk = fs->fs_dev->disk; struct ext2_sb_info *sbi; struct ext2_super_block sb; struct cache *cs; /* read the super block */ disk->rdwr_sectors(disk, &sb, 2, 2, 0); /* check if it is ext2, since we also support btrfs now */ if (sb.s_magic != EXT2_SUPER_MAGIC) return -1; sbi = malloc(sizeof(*sbi)); if (!sbi) { malloc_error("ext2_sb_info structure"); return -1; } fs->fs_info = sbi; if (sb.s_magic != EXT2_SUPER_MAGIC) { printf("ext2 mount error: it's not a EXT2/3/4 file system!\n"); return 0; } fs->sector_shift = disk->sector_shift; fs->block_shift = sb.s_log_block_size + 10; fs->sector_size = 1 << fs->sector_shift; fs->block_size = 1 << fs->block_shift; sbi->s_inodes_per_group = sb.s_inodes_per_group; sbi->s_blocks_per_group = sb.s_blocks_per_group; sbi->s_inodes_per_block = BLOCK_SIZE(fs) / sb.s_inode_size; if (sb.s_desc_size < sizeof(struct ext2_group_desc)) sb.s_desc_size = sizeof(struct ext2_group_desc); sbi->s_desc_per_block = BLOCK_SIZE(fs) / sb.s_desc_size; sbi->s_groups_count = (sb.s_blocks_count - sb.s_first_data_block + EXT2_BLOCKS_PER_GROUP(fs) - 1) / EXT2_BLOCKS_PER_GROUP(fs); sbi->s_first_data_block = sb.s_first_data_block; sbi->s_inode_size = sb.s_inode_size; /* Volume UUID */ memcpy(sbi->s_uuid, sb.s_uuid, sizeof(sbi->s_uuid)); /* Initialize the cache, and force block zero to all zero */ cache_init(fs->fs_dev, fs->block_shift); cs = _get_cache_block(fs->fs_dev, 0); memset(cs->data, 0, fs->block_size); cache_lock_block(cs); return fs->block_shift; }
/* * allocating the resources for the game+initiallizing it * throws calloc errors */ void allocateChess(int isGUI) { mainGame = (Game*)malloc(sizeof(Game)); if(mainGame==NULL){ calloc_error(); standart_fail=true; return;} /* setting startingGameSetting to save the starting state */ mainGame->gameInfo=(game *)malloc(sizeof(game)); if(mainGame->gameInfo==NULL){ malloc_error(); standart_fail=1; free(mainGame); return; } mainGame->gameInfo->boardPointer = (chessboard *)calloc((BOARD_SIZE * BOARD_SIZE), sizeof(char)); if(mainGame->gameInfo->boardPointer==NULL){ calloc_error(); standart_fail=1; free(mainGame->gameInfo); free(mainGame); return; } if(isGUI){ mainGame->startingGameSettings=(game *)malloc(sizeof(game)); if(mainGame->startingGameSettings==NULL){ malloc_error(); standart_fail=1; free(mainGame->gameInfo->boardPointer); free(mainGame->gameInfo); free(mainGame); return; } mainGame->startingGameSettings->boardPointer=(chessboard *)calloc((BOARD_SIZE * BOARD_SIZE), sizeof(char)); if(mainGame->startingGameSettings->boardPointer==NULL){ malloc_error(); standart_fail=1; free(mainGame->startingGameSettings); free(mainGame->gameInfo->boardPointer); free(mainGame->gameInfo); free(mainGame); return; } initializeSlots(); if(standart_fail){ deleteChessGame(isGUI); return;} } initializeChess(isGUI); if(standart_fail){ deleteChessGame(isGUI); if(isGUI){deleteSlots(SLOT_NUM);} return; } }
/* * Allocate a local UDP port structure and assign it a local port number. * Return the inode pointer if success, or null if failure */ static struct inode *allocate_socket(struct fs_info *fs) { struct inode *inode = alloc_inode(fs, 0, sizeof(struct pxe_pvt_inode)); if (!inode) { malloc_error("socket structure"); } else { inode->mode = DT_REG; /* No other types relevant for PXE */ } return inode; }
void Phreeqc:: fpunchf(const char *name, const char *format, int d) { try { if (phrq_io) phrq_io->fpunchf(name, format, d); } catch(std::bad_alloc) { malloc_error(); } }
/* ---------------------------------------------------------------------- */ struct spread_row * copy_row (struct spread_row *spread_row_ptr) /* ---------------------------------------------------------------------- */ { int i; struct spread_row *new_spread_row_ptr; /* * Allocate space */ new_spread_row_ptr = (struct spread_row *) PHRQ_malloc ((size_t) sizeof (struct spread_row)); if (new_spread_row_ptr == NULL) malloc_error (); new_spread_row_ptr->char_vector = (char **) PHRQ_malloc ((size_t) spread_row_ptr->count * sizeof (char *)); if (new_spread_row_ptr->char_vector == NULL) malloc_error (); new_spread_row_ptr->d_vector = (LDBLE *) PHRQ_malloc ((size_t) spread_row_ptr->count * sizeof (LDBLE)); if (new_spread_row_ptr->d_vector == NULL) malloc_error (); new_spread_row_ptr->type_vector = (int *) PHRQ_malloc ((size_t) spread_row_ptr->count * sizeof (int)); if (new_spread_row_ptr->type_vector == NULL) malloc_error (); for (i = 0; i < spread_row_ptr->count; i++) { new_spread_row_ptr->char_vector[i] = string_duplicate (spread_row_ptr->char_vector[i]); new_spread_row_ptr->d_vector[i] = spread_row_ptr->d_vector[i]; new_spread_row_ptr->type_vector[i] = spread_row_ptr->type_vector[i]; } new_spread_row_ptr->count = spread_row_ptr->count; new_spread_row_ptr->empty = spread_row_ptr->empty; new_spread_row_ptr->number = spread_row_ptr->number; new_spread_row_ptr->string = spread_row_ptr->string; return new_spread_row_ptr; }
/* * eval_libc_valid - We run this function to make sure that the * libc malloc can run to completion on the set of traces. * We'll be conservative and terminate if any libc malloc call fails. * */ static int eval_libc_valid(trace_t *trace, int tracenum) { int i, newsize; char *p, *newp, *oldp; for (i = 0; i < trace->num_ops; i++) { switch (trace->ops[i].type) { case ALLOC: /* malloc */ if ((p = malloc(trace->ops[i].size)) == NULL) { malloc_error(tracenum, i, "libc malloc failed"); unix_error("System message"); } trace->blocks[trace->ops[i].index] = p; break; case REALLOC: /* realloc */ newsize = trace->ops[i].size; oldp = trace->blocks[trace->ops[i].index]; if ((newp = realloc(oldp, newsize)) == NULL) { malloc_error(tracenum, i, "libc realloc failed"); unix_error("System message"); } trace->blocks[trace->ops[i].index] = newp; break; case FREE: /* free */ free(trace->blocks[trace->ops[i].index]); break; default: app_error("invalid operation type in eval_libc_valid"); } } return 1; }
/* Split text into the matching re substrings - Perl is so much easier :). * Each element of *string is set to a malloced copy of the substring or * NULL if the substring did not match (undef). A zero length substring match * is represented by a zero length **string. */ void re_strings(regex_t *preg, const char *text, regmatch_t *pmatch, char ***string) { int i; if (!*string) { *string = malloc((preg->re_nsub+1)*sizeof(**string)); if (!*string) malloc_error("re_strings base"); for (i = 0; i < preg->re_nsub+1; ++i) (*string)[i] = NULL; } for (i = 0; i < preg->re_nsub+1; ++i) { if (debug > 4) fprintf(stderr, "DEBUG: re_string %d offsets %d %d", i, pmatch[i].rm_so, pmatch[i].rm_eo); if (pmatch[i].rm_so == -1) { /* no match for this sub expression */ free((*string)[i]); (*string)[i] = NULL; if (debug > 4) fprintf(stderr, " (undef)\n"); } else { int l = pmatch[i].rm_eo - pmatch[i].rm_so + 1; char *p; p = malloc(l); if (!p) malloc_error("re_strings"); strncpy(p, text+pmatch[i].rm_so, l-1); *(p+l-1) = '\0'; (*string)[i] = p; if (debug > 4) fprintf(stderr, " '%s'\n", p); } } }
/* ---------------------------------------------------------------------- */ void add_row (struct spread_row *spread_row_ptr) /* ---------------------------------------------------------------------- */ { g_spread_sheet.rows = (struct spread_row **) PHRQ_realloc (g_spread_sheet.rows, sizeof (struct spread_row *) * (g_spread_sheet.count_rows + 1)); if (g_spread_sheet.rows == NULL) { malloc_error (); } else { g_spread_sheet.rows[g_spread_sheet.count_rows++] = copy_row (spread_row_ptr); } }
t_color *rec_color(char *str) { int i; char s[3]; t_color *ret; i = 0; if (!(ret = (t_color *)malloc(sizeof(t_color)))) malloc_error(); while (str[i] != '"') i++; i++; s[2] = '\0'; ret->r = ft_xtoi(ft_memcpy(s, &str[i], 2)); ret->g = ft_xtoi(ft_memcpy(s, &str[i + 2], 2)); ret->b = ft_xtoi(ft_memcpy(s, &str[i + 4], 2)); ret->r /= 255; ret->g /= 255; ret->b /= 255; return (ret); }
void Phreeqc:: fpunchf_user(int user_index, const char *format, double d) { const char *name; if (current_user_punch == NULL) return; // check headings //if (user_index < user_punch_count_headings) int user_punch_count_headings = (int) current_user_punch->Get_headings().size(); if (user_index < user_punch_count_headings) { //name = user_punch_headings[user_index]; name = current_user_punch->Get_headings()[user_index].c_str(); } else { if (fpunchf_user_s_warning == 0) { error_string = sformatf( "USER_PUNCH: Headings count does not match number of calls to PUNCH.\n"); warning_msg(error_string); fpunchf_user_s_warning = 1; } sprintf(fpunchf_user_buffer, "no_heading_%d", (user_index - user_punch_count_headings) + 1); name = fpunchf_user_buffer; } try { if (phrq_io) phrq_io->fpunchf(name, format, (double) d); } catch(std::bad_alloc) { malloc_error(); } }
int texteditor(char *text, int maxchars, const int startrow, const int startcol,int maxrows,const int maxcols,const int displayrows,const int returnhandler,const char *permitted, bool ins, const bool allowcr) { int ky,position=0,row,col,scrollstart=0, x=0, y=0; //ky is most of the time the input user gives, position(it stays in sync with cursor) points to text row and col keep track of row or column being managed, scroll start keeps track of position from where scroll starts, x and y are xy coordinates on screen char *where, *original, *savetext,**display, *last_undo; // where keeps the line of text for a while, original is the text as copied from text file bool exitflag=false; // save text is used to keep a backup of our text so we may get previous text bac if something unusuall happens // last undo is useless // display is 2 dimensional array to keep enough text in it to fill the diplay window if (!maxchars) // if user has not specified maxchars maxchars=maxrows*maxcols+1; if (!maxrows || maxrows > maxchars-1) // if maxrows are not specified or maxchars are less then number of rows possible then make sure max rows are less then maxchars maxrows=maxchars-1; if (ins) // if ins variable is set curs_set(2); //then set cursor to high visibility mode else //else keep it normal curs_set(1); /* below we will allocate memory to our above declared arrays and assign data to them*/ if ((display = malloc(maxrows * sizeof(char *))) ==NULL) /*assign memory equal to number of maxrows to display*/ malloc_error(); //call the function to check if memory was successfully allocated for(ky = 0; ky < maxrows; ky++) //now traverse all rows in display and allocated and assign memory equal to maxcols to each row of display if ((display[ky] = malloc((maxcols+1) * sizeof(char)))==NULL) malloc_error(); if ((original=malloc(maxchars*sizeof(char)))==NULL) //allocated memory to original malloc_error(); strcpy(original,text);//copy text taken from file to original variable if ((savetext=malloc(maxchars*sizeof(char)))==NULL)// allocate memory to savetext malloc_error(); strcpy(savetext,text);//copy text to savetext /*finished assigning**/ while (!exitflag) // our loop to stay in unless user presses a button to turn exit flag true initially it is set false { int counter; //counter to count do //start of do while loop { counter=0; where=text; //temporarily copy all text taken from file to where for (row=0; row < maxrows; row++) // initialize display vriable making sure every row has a null in the start { display[row][0]=127; //assign a backspace character to first column of every row display[row][1]='\0'; //assign a null character to second column of every row indicating that the row ends here } row=0; // set row to zero while ((strlen(where) > maxcols || strchr(where,'\n') != NULL) && (display[maxrows-1][0]==127 || display[maxrows-1][0]=='\n')) //while loop //keep traversing if both of following conditions are met successfully //1. length of text(where) is more than number of columns which means there are more than one rows // "OR" if a new row exist //2. if first column of last row has a backspace OR an end of line character(means we haev not reached last row yet) { strncpy(display[row],where,maxcols); //copy text from where to current row of display from where specifyint he maximum columns it can have display[row][maxcols]='\0'; // insert a null at the end of a row indicating that the row ends here if (strchr(display[row],'\n') != NULL) // if there s a new line character in this row left(display[row],strchr(display[row],'\n')-display[row]);//end the row where a new line character is found else //in case there is no newline character in this row left(display[row],strrchr(display[row],' ')-display[row]);//mark end of row at next white space charcter if (display[maxrows-1][0]==127 || display[maxrows-1][0]=='\n')//if first column of last row has a backspace OR an end of line character { where+=strlen(display[row]); // move where pointer to the address before which text is already dealt with if (where[0]=='\n' || where[0]==' ' || where[0]=='\0') //in case where points to and of newline characters where++; //move one step forward row++; //current is dealt with now we move to next row } }// while loop ends here text is assigned to display datas tructure properly if (row == maxrows-1 && strlen(where) > maxcols) // if we have reached last row and remaining text is more than number of characters last row can have { strcpy(text,savetext); //copy the savetext to text if (ky==127/*KEY_BACKSPACE*/) //if ky is KEY_BACKSPACE position++; //increase position variable counter=1; //set counter to be one since there is text remaining to be copied } }while (counter);//do while loop ends here strcpy(display[row],where);//now copy remaining text from where to display row ky=0; //set ky to be 0 if (strchr(display[maxrows-1],'\n') != NULL) //if first character of last row is a newline character if (strchr(display[maxrows-1],'\n')[1] != '\0') //and second charcter is a newline character ky=127/*KEY_BACKSPACE*/; //then set ky to be equal to backspace col=position; //set current column to be equal to position of cursor we are at row=0; // set row to pont to fisrt row counter=0; //set counter to be 0 while (col > strlen(display[row])) //keep traversing if column is greator than number of columsn in current row { col-=strlen(display[row]); //set column= column - number of columns of current row counter+=strlen(display[row]); //set counter to point at the end of current row if (text[counter] ==' ' || text[counter]=='\n' || text[counter]=='\0') //in case text at current cursor position is a newline character { col--; //decrease col by one counter++; //point to text charcter in text } row++; //increase row by one since current row has been properly taken care of } if (col > maxcols-1) //in case col is greator than total number of columns a row can hev { row++; //move to next row means increment row variable col=0; //set col = 0 means point to first colunmn in next row } if (!ky) // otherwise ky==KEY_BACKSPACE and we're getting rid of the last character we entered to avoid pushing text into the last line +1 { if (row < scrollstart) // in case current row is lower than scroll start scrollstart--; // then decrease scroll start if (row > scrollstart+displayrows-1) //in case current row is greator than scroll start plus number of displayrows scrollstart++; //then increase scroll start for (counter=0;counter < displayrows; counter++) //traverse all the display rows { mvhline(counter+startrow,startcol,' ',maxcols); //move to position counter+startrow on y coordinate and startcol on x coordinate and print spaces on all columns onwards from counter of this row if (display[counter+scrollstart][0] != 127) //if current position has a backspace in it then mvprintw(counter+startrow,startcol,"%s",display[counter+scrollstart]);//move to position counter+startrow on y and startcol on x and display text in display area } move(row+startrow-scrollstart,col+startcol); // move to end of text ky=getch(); // text has been displayed now wait for user to press a key } switch(ky) // take actions based on pressed key { case 27: //escape exitflag=true; //set exitflag to be true break; case KEY_F(2): //f2 key to delete all file contents memset(text,'\0',maxchars); //make all the contens of file to be null position=0; //set postion to be zero scrollstart=0; //set scroll start to be zero break; case KEY_F(3): //f3 key to search for strings getyx(stdscr,y,x);//get current coordinates of cursor remove_search_marks(text);//remove searchmarks from text search_string(NULL,text); //goto search function clr_bottom(); //clear the interactive area below menu move(y,x); //move back to textbox break; case KEY_F(4): //f4 to replace strings getyx(stdscr,y,x); //get current coordinates of cursor replace_string(text);//call the function to replace string clr_bottom(); move(y,x); break; case KEY_F(5): //f5 key to save file getyx(stdscr,y,x); save_file(text); //call the function save file clr_bottom(); move(y,x); break; case KEY_F(6): //f6 key to count number of words clr_bottom(); count_words_chars(text); //call the function to count words and chars in text case KEY_F(7): //f7 key to remove search marks remove_search_marks(text); //remove search marks case KEY_HOME: //move to start of current row if (col) //if current column is not the first column { position=0;//set position to be zero for (col=0; col < row; col++)//traverse until col is less then row { position += strlen(display[col]);//move cursor to end of current row in display array if ((strchr(display[row],'\n') != NULL) || (strchr(display[row],' ') != NULL))//if there is a escape character ' ' or '\n' in current row position++; // increment position and move to start of the row } } break; case KEY_END: //move to end of current row if (col < strlen(display[row])) //if col is less than number of columns in current row { position=-1; //set potiion to -1 for (col=0; col <=row; col++) //traverse until col is less than or equal to row (row is position of current row) { position+=strlen(display[col]);//set position to be the end of curent row if ((strchr(display[row],'\n') != NULL) || (strchr(display[row],' ') != NULL)) //if we haev reached enf of row position++; //increment position so it may move to end of current row } } break; case KEY_PPAGE: //move to start of text position=0; //set position to be zero scrollstart=0; //set scroll start to be zero break; case KEY_NPAGE: //move to end of text position=strlen(text); //set postion to be end of text for (counter=0; counter < maxrows; counter++) //traverse until counter is less than total number of rows if(display[counter][0]==127) //if the row at position counter's first character is backspace break; //then break from loop scrollstart=counter-displayrows; //else set scroll start to equal counter-displayrows if (scrollstart < 0) //in case scroll start has decreased to become negative scrollstart=0; //set it to be zero again break; case KEY_LEFT: //move cursor left if (position) //if position is not zero position--; //decrease by one break; case KEY_RIGHT: //move cursor right if (position < strlen(text) && (row != maxrows-1 || col < maxcols-1))//if cursor is not already at end or far from end position++; //increase position by one break; case KEY_UP: //move cursor up if (row) //in case we are not on first row { if (col > strlen(display[row-1]))//if current column is greater then length of previous row position=strlen(display[row-1]); //then set cursor at the end of above row else position=col; //else set position to col ky=0; //set ky=0 for (col=0; col < row-1; col++) //traverse for col less than row above current row { position+=strlen(display[col]); //move cursor to end of column ky+=strlen(display[col]); //move ky to next row if ((strlen(display[col]) < maxcols) || (text[ky]==' ' && strlen(display[col])==maxcols))//if we are not already at end of row { position++; //increment position ky++; //move to next row } } } break; case KEY_DOWN:// move cursor to below row if (row < maxrows-1) //if it's not last row if (display[row+1][0] !=127) //if next row is not empty { if (col < strlen(display[row+1])) //if col is less than length of next row position=col; //set position to be col else position=strlen(display[row+1]);//set position to be end of above row ky=0;//set ky=0; for (col=0; col <= row; col++)//traverse until we reach the current row { position+=strlen(display[col]);//move to next row ky+=strlen(display[col]);//move to next row if ((strlen(display[col]) < maxcols) || (text[ky]==' ' && strlen(display[col])==maxcols))//if we are not already at end of row { position++; ky++; } } } break; case KEY_IC: // insert key ins=!ins;//invert the insert mode, turn it on if it's on or vice versa if (ins) curs_set(2); else curs_set(1); break; case 330://KEY_DC: // delete key if (strlen(text))//if text exist { strcpy(savetext,text);//save text memmove(&text[position],&text[position+1],maxchars-position);//move text to left by one character meanwhile eating the one character, search google for function memove and read about it... } break; case KEY_BACKSPACE:// remove text if (strlen(text) && position)//if text exist and cursor is already not at begiing of text { strcpy(savetext,text);//save text position--;//decrease poition by one basically making cursor go back memmove(&text[position],&text[position+1],maxchars-position);//move text to left by one character meanwhile eating the one character } break; case 25: // ctrl-y delete entire line if (display[1][0] != 127)//if there's text on first row { position-=col;//move cursor to start of first row ky=0;//set ky=0 do { memmove(&text[position],&text[position+1],maxchars-position);//move text right by one ky++;//increase ky } while (ky < strlen(display[row]));//keep doing it until ky is less than number of columns in current row } else memset(text,'\0',maxchars);//other wise it's already empty break; case 10: // return // insert a line by pressing return button switch (returnhandler)//see what do we want enter to do { case 1:// in case return handler==1 if (display[maxrows-1][0] == 127 || display[maxrows-1][0] == '\n')// if display area is not empty { memmove(&text[position+1],&text[position],maxchars-position);//move text to right by one, emptying the space for one charectre at potiions text[position]='\n'; //insert a new row character at position in text position++;//increase poition } break; case 2: ky=' ';//insert a space ungetch(ky);// break; case 3: exitflag=true;//exit } break; default: //in case of any other characters than specified above if (((permitted==NULL && ky > 31 && ky < 127) || (permitted != NULL && strchr(permitted,ky))) && strlen(text) < maxchars-1 && (row !=maxrows-1 || (strlen(display[maxrows-1]) < maxcols || (ins && (row!=maxrows-1 && col < maxcols ))))) { if (ins || text[position+1]=='\n' || text[position]== '\n') //in ase insert mode is on or there is no text after this in current row memmove(&text[position+1],&text[position],maxchars-position);//move text to right by one and add characters text[position]=ky;//insert current key in text if (row != maxrows-1 || col < maxcols-1)//in case insert mode is off and we're not at the end of row position++;//increment position(move cursor to right) } } if(!allowcr)//if isnert mode is allowed if (text[0]=='\n') //if first char in text is a newline { memmove(&text[0],&text[1],maxchars-1);//movetext to left by one if (position)//if position is not zero position--;//decrease position } }//switch ends here /*user decided to exit free all assigned memory */ free(original);//free memory of original free(savetext);//free memory of savetext free(last_undo);//free memory of last undo, it's not used at all so no need for it for(scrollstart = 0; scrollstart < maxrows; scrollstart++)//traverse all rows of siplay and free their memory free(display[scrollstart]); free(display);//free dispay /************************/ return 0; }
/* ---------------------------------------------------------------------- */ int spread_row_to_solution (struct spread_row *heading, struct spread_row *units, struct spread_row *data, struct defaults defaults) /* ---------------------------------------------------------------------- */ { int i, j, n, l, next_keyword_save; int n_user, n_user_end; int default_pe, alk; int count_isotopes; int max_mass_balance, count_mass_balance; char *ptr, *ptr1; char *description; char token[MAX_LENGTH], token1[MAX_LENGTH]; char string[2 * MAX_LENGTH]; LDBLE dummy; int return_value, opt; char *next_char; const char *opt_list[] = { "temp", /* 0 */ "temperature", /* 1 */ "dens", /* 2 */ "density", /* 3 */ "units", /* 4 */ "redox", /* 5 */ "ph", /* 6 */ "pe", /* 7 */ "unit", /* 8 */ "isotope", /* 9 */ "water", /* 10 */ "description", /* 11 */ "desc", /* 12 */ "descriptor" /* 13 */ }; int count_opt_list = 14; /* * look for solution number */ n_user = -1; n_user_end = -1; description = string_duplicate (""); for (i = 0; i < heading->count; i++) { if (strcmp_nocase (heading->char_vector[i], "number") == 0) { break; } } if (i == heading->count || data->type_vector[i] == EMPTY || data->count <= i) { n_user = -1; #ifdef SKIP for (i = 0; i < count_solution; i++) { if (n_user <= solution[i]->n_user) { n_user = solution[i]->n_user + 1; } } #endif } else if (data->type_vector[i] == STRING) { input_error++; sprintf (error_string, "Expected solution number or number range in 'number' column, found: %s.", data->char_vector[i]); error_msg (error_string, CONTINUE); } else { strcpy (string, "solution_s "); strcat (string, data->char_vector[i]); ptr = string; description = (char *) free_check_null (description); next_keyword_save = next_keyword; next_keyword = 42; read_number_description (ptr, &n_user, &n_user_end, &description); next_keyword = next_keyword_save; } /* * set up solution */ if (n_user >= 0 && solution_bsearch (n_user, &n, FALSE) != NULL) { solution_free (solution[n]); } else { n = count_solution++; if (count_solution >= max_solution) { space ((void **) ((void *) &(solution)), count_solution, &max_solution, sizeof (struct solution *)); } } solution[n] = solution_alloc (); solution[n]->n_user = n_user; solution[n]->n_user_end = n_user_end; if (use.solution_in == FALSE) { use.solution_in = TRUE; use.n_solution_user = n_user; } max_mass_balance = MAX_MASS_BALANCE; /* * Set default ph, temp, density, pe, units */ solution[n]->description = description; solution[n]->tc = defaults.temp; solution[n]->ph = defaults.ph; solution[n]->density = defaults.density; solution[n]->solution_pe = defaults.pe; solution[n]->mass_water = defaults.water; solution[n]->ah2o = 1.0; solution[n]->mu = 1e-7; solution[n]->cb = 0.0; default_pe = 0; solution[n]->units = defaults.units; solution[n]->totals[0].description = NULL; count_mass_balance = 0; count_isotopes = 0; default_pe = pe_data_store (&(solution[n]->pe), defaults.redox); /* * Read concentration data */ return_value = UNKNOWN; for (i = 0; i < heading->count; i++) { if (strcmp_nocase (heading->char_vector[i], "number") == 0) continue; if (strcmp_nocase (heading->char_vector[i], "uncertainty") == 0) continue; if (strcmp_nocase (heading->char_vector[i], "uncertainties") == 0) continue; if (strcmp_nocase (heading->char_vector[i], "isotope_uncertainty") == 0) continue; /* * Copy in element name */ if (heading->type_vector[i] == EMPTY) continue; strcpy (string, heading->char_vector[i]); strcat (string, " "); /* * Copy in concentration data */ if (i >= data->count || data->type_vector[i] == EMPTY) continue; strcat (string, data->char_vector[i]); strcat (string, " "); /* * Copy in concentration data */ if (units != NULL && i < units->count && units->type_vector[i] != EMPTY) { strcat (string, units->char_vector[i]); } /* * Parse string just like read_solution input */ next_char = string; opt = get_option_string (opt_list, count_opt_list, &next_char); if (opt == OPTION_DEFAULT && heading->type_vector[i] == NUMBER) { opt = 9; } switch (opt) { case OPTION_EOF: /* end of file */ return_value = EOF; break; case OPTION_KEYWORD: /* keyword */ return_value = KEYWORD; break; case OPTION_ERROR: input_error++; error_msg ("Unknown input in SOLUTION keyword.", CONTINUE); error_msg (line_save, CONTINUE); break; case 0: /* temperature */ case 1: sscanf (next_char, SCANFORMAT, &(solution[n]->tc)); break; case 2: /* density */ case 3: sscanf (next_char, SCANFORMAT, &(solution[n]->density)); break; case 4: /* units */ case 8: /* unit */ if (copy_token (token, &next_char, &l) == EMPTY) break; if (check_units (token, FALSE, FALSE, solution[n]->units, TRUE) == OK) { solution[n]->units = string_hsave (token); } else { input_error++; } break; case 5: /* redox */ if (copy_token (token, &next_char, &l) == EMPTY) break; if (parse_couple (token) == OK) { default_pe = pe_data_store (&(solution[n]->pe), token); } else { input_error++; } break; case 6: /* ph */ next_char = string; if (read_conc (n, count_mass_balance, next_char) == ERROR) { input_error++; break; } solution[n]->ph = solution[n]->totals[count_mass_balance].input_conc; if (solution[n]->totals[count_mass_balance].equation_name == NULL) { break; } solution[n]->totals[count_mass_balance].description = string_hsave ("H(1)"); count_mass_balance++; break; case 7: /* pe */ next_char = string; if (read_conc (n, count_mass_balance, next_char) == ERROR) { input_error++; break; } solution[n]->solution_pe = solution[n]->totals[count_mass_balance].input_conc; if (solution[n]->totals[count_mass_balance].equation_name == NULL) { break; } solution[n]->totals[count_mass_balance].description = string_hsave ("E"); count_mass_balance++; break; case 9: /* isotope */ next_char = string; if (copy_token (token, &next_char, &l) != DIGIT) { input_error++; sprintf (error_string, "Expected isotope name to" " begin with an isotopic number."); error_msg (error_string, CONTINUE); continue; } solution[n]->isotopes = (struct isotope *) PHRQ_realloc (solution[n]->isotopes, (size_t) (count_isotopes + 1) * sizeof (struct isotope)); if (solution[n]->isotopes == NULL) malloc_error (); /* read and save element name */ ptr1 = token; get_num (&ptr1, &(solution[n]->isotopes[count_isotopes].isotope_number)); if (ptr1[0] == '\0' || isupper ((int) ptr1[0]) == FALSE) { error_msg ("Expecting element name.", CONTINUE); error_msg (line_save, CONTINUE); input_error++; return (ERROR); } solution[n]->isotopes[count_isotopes].elt_name = string_hsave (ptr1); /* read and store isotope ratio */ if (copy_token (token, &next_char, &l) != DIGIT) { input_error++; sprintf (error_string, "Expected numeric value for isotope ratio."); error_msg (error_string, CONTINUE); continue; } sscanf (token, SCANFORMAT, &(solution[n]->isotopes[count_isotopes].ratio)); /* read and store isotope ratio uncertainty */ /* first choice is next column */ if ((i + 1) < heading->count && (strcmp_nocase (heading->char_vector[i + 1], "uncertainty") == 0 || strcmp_nocase (heading->char_vector[i + 1], "isotope_uncertainty") == 0 || strcmp_nocase (heading->char_vector[i + 1], "uncertainties") == 0) && (i + 1) < data->count && data->type_vector[i + 1] == NUMBER) { solution[n]->isotopes[count_isotopes].ratio_uncertainty = data->d_vector[i + 1]; } else { next_char = string; copy_token (token, &next_char, &l); for (j = 0; j < defaults.count_iso; j++) { if (strcmp (token, defaults.iso[j].name) == 0) { solution[n]->isotopes[count_isotopes].ratio_uncertainty = defaults.iso[j].uncertainty; break; } } if (j == defaults.count_iso) { solution[n]->isotopes[count_isotopes].ratio_uncertainty = NAN; } } count_isotopes++; break; case 10: /* water */ j = copy_token (token, &next_char, &l); if (j == EMPTY) { solution[n]->mass_water = 1.0; } else if (j != DIGIT) { input_error++; sprintf (error_string, "Expected numeric value for mass of water in solution."); error_msg (error_string, CONTINUE); } else { sscanf (token, SCANFORMAT, &dummy); solution[n]->mass_water = (LDBLE) dummy; } break; case 11: /* description */ case 12: /* desc */ case 13: /* descriptor */ solution[n]->description = (char *) free_check_null (solution[n]->description); solution[n]->description = string_duplicate (next_char); break; case OPTION_DEFAULT: /* * Read concentration */ next_char = string; if (copy_token (token, &next_char, &l) == LOWER) continue; next_char = string; if (read_conc (n, count_mass_balance, next_char) == ERROR) { #ifdef SKIP input_error++; break; #endif } count_mass_balance++; break; } if (count_mass_balance + 1 >= max_mass_balance) { space ((void **) ((void *) &(solution[n]->totals)), count_mass_balance + 1, &max_mass_balance, sizeof (struct conc)); } if (return_value == EOF || return_value == KEYWORD) break; } /* * Sort totals by description */ qsort (solution[n]->totals, (size_t) count_mass_balance, (size_t) sizeof (struct conc), conc_compare); /* * fix up default units and default pe */ for (i = 0; i < count_mass_balance; i++) { strcpy (token, solution[n]->totals[i].description); str_tolower (token); if (solution[n]->totals[i].units == NULL) { solution[n]->totals[i].units = solution[n]->units; } else { alk = FALSE; if (strstr (token, "alk") == token) alk = TRUE; strcpy (token1, solution[n]->totals[i].units); if (check_units (token1, alk, TRUE, solution[n]->units, TRUE) == ERROR) { input_error++; } else { solution[n]->totals[i].units = string_hsave (token1); } } if (solution[n]->totals[i].n_pe < 0) { solution[n]->totals[i].n_pe = default_pe; } } solution[n]->default_pe = default_pe; /* * Mark end of solution */ solution[n]->totals[count_mass_balance].description = NULL; solution[n]->count_isotopes = count_isotopes; if (count_isotopes > 0) { qsort (solution[n]->isotopes, (size_t) count_isotopes, (size_t) sizeof (struct isotope), isotope_compare); } else { solution[n]->isotopes = (struct isotope *) free_check_null (solution[n]->isotopes); } return (return_value); }
int cl1mp (int k, int l, int m, int n, int nklmd, int n2d, LDBLE * q_arg, int *kode_arg, LDBLE toler_arg, int *iter, LDBLE * x_arg, LDBLE * res_arg, LDBLE * error_arg, LDBLE * cu_arg, int *iu, int *s, int check, LDBLE censor_arg) { /* System generated locals */ union double_or_int { int ival; mpf_t dval; } *q2; /* Local variables */ static int nklm; static int iout, i, j; static int maxit, n1, n2; static int ia, ii, kk, in, nk, js; static int iphase, kforce; static int klm, jmn, nkl, jpn; static int klm1; static int *kode; int q_dim, cu_dim; int iswitch; mpf_t *q; mpf_t *x; mpf_t *res; mpf_t error; mpf_t *cu; mpf_t dummy, dummy1, sum, z, zu, zv, xmax, minus_one, toler, check_toler; /*mpf_t *scratch; */ mpf_t pivot, xmin, cuv, tpivot, sn; mpf_t zero; int censor; mpf_t censor_tol; /* THIS SUBROUTINE USES A MODIFICATION OF THE SIMPLEX */ /* METHOD OF LINEAR PROGRAMMING TO CALCULATE AN L1 SOLUTION */ /* TO A K BY N SYSTEM OF LINEAR EQUATIONS */ /* AX=B */ /* SUBJECT TO L LINEAR EQUALITY CONSTRAINTS */ /* CX=D */ /* AND M LINEAR INEQUALITY CONSTRAINTS */ /* EX.LE.F. */ /* DESCRIPTION OF PARAMETERS */ /* K NUMBER OF ROWS OF THE MATRIX A (K.GE.1). */ /* L NUMBER OF ROWS OF THE MATRIX C (L.GE.0). */ /* M NUMBER OF ROWS OF THE MATRIX E (M.GE.0). */ /* N NUMBER OF COLUMNS OF THE MATRICES A,C,E (N.GE.1). */ /* KLMD SET TO AT LEAST K+L+M FOR ADJUSTABLE DIMENSIONS. */ /* KLM2D SET TO AT LEAST K+L+M+2 FOR ADJUSTABLE DIMENSIONS. */ /* NKLMD SET TO AT LEAST N+K+L+M FOR ADJUSTABLE DIMENSIONS. */ /* N2D SET TO AT LEAST N+2 FOR ADJUSTABLE DIMENSIONS */ /* Q TWO DIMENSIONAL REAL ARRAY WITH KLM2D ROWS AND */ /* AT LEAST N2D COLUMNS. */ /* ON ENTRY THE MATRICES A,C AND E, AND THE VECTORS */ /* B,D AND F MUST BE STORED IN THE FIRST K+L+M ROWS */ /* AND N+1 COLUMNS OF Q AS FOLLOWS */ /* A B */ /* Q = C D */ /* E F */ /* THESE VALUES ARE DESTROYED BY THE SUBROUTINE. */ /* KODE A CODE USED ON ENTRY TO, AND EXIT */ /* FROM, THE SUBROUTINE. */ /* ON ENTRY, THIS SHOULD NORMALLY BE SET TO 0. */ /* HOWEVER, IF CERTAIN NONNEGATIVITY CONSTRAINTS */ /* ARE TO BE INCLUDED IMPLICITLY, RATHER THAN */ /* EXPLICITLY IN THE CONSTRAINTS EX.LE.F, THEN KODE */ /* SHOULD BE SET TO 1, AND THE NONNEGATIVITY */ /* CONSTRAINTS INCLUDED IN THE ARRAYS X AND */ /* RES (SEE BELOW). */ /* ON EXIT, KODE HAS ONE OF THE */ /* FOLLOWING VALUES */ /* 0- OPTIMAL SOLUTION FOUND, */ /* 1- NO FEASIBLE SOLUTION TO THE */ /* CONSTRAINTS, */ /* 2- CALCULATIONS TERMINATED */ /* PREMATURELY DUE TO ROUNDING ERRORS, */ /* 3- MAXIMUM NUMBER OF ITERATIONS REACHED. */ /* TOLER A SMALL POSITIVE TOLERANCE. EMPIRICAL */ /* EVIDENCE SUGGESTS TOLER = 10**(-D*2/3), */ /* WHERE D REPRESENTS THE NUMBER OF DECIMAL */ /* DIGITS OF ACCURACY AVAILABLE. ESSENTIALLY, */ /* THE SUBROUTINE CANNOT DISTINGUISH BETWEEN ZERO */ /* AND ANY QUANTITY WHOSE MAGNITUDE DOES NOT EXCEED */ /* TOLER. IN PARTICULAR, IT WILL NOT PIVOT ON ANY */ /* NUMBER WHOSE MAGNITUDE DOES NOT EXCEED TOLER. */ /* ITER ON ENTRY ITER MUST CONTAIN AN UPPER BOUND ON */ /* THE MAXIMUM NUMBER OF ITERATIONS ALLOWED. */ /* A SUGGESTED VALUE IS 10*(K+L+M). ON EXIT ITER */ /* GIVES THE NUMBER OF SIMPLEX ITERATIONS. */ /* X ONE DIMENSIONAL REAL ARRAY OF SIZE AT LEAST N2D. */ /* ON EXIT THIS ARRAY CONTAINS A */ /* SOLUTION TO THE L1 PROBLEM. IF KODE=1 */ /* ON ENTRY, THIS ARRAY IS ALSO USED TO INCLUDE */ /* SIMPLE NONNEGATIVITY CONSTRAINTS ON THE */ /* VARIABLES. THE VALUES -1, 0, OR 1 */ /* FOR X(J) INDICATE THAT THE J-TH VARIABLE */ /* IS RESTRICTED TO BE .LE.0, UNRESTRICTED, */ /* OR .GE.0 RESPECTIVELY. */ /* RES ONE DIMENSIONAL REAL ARRAY OF SIZE AT LEAST KLMD. */ /* ON EXIT THIS CONTAINS THE RESIDUALS B-AX */ /* IN THE FIRST K COMPONENTS, D-CX IN THE */ /* NEXT L COMPONENTS (THESE WILL BE =0),AND */ /* F-EX IN THE NEXT M COMPONENTS. IF KODE=1 ON */ /* ENTRY, THIS ARRAY IS ALSO USED TO INCLUDE SIMPLE */ /* NONNEGATIVITY CONSTRAINTS ON THE RESIDUALS */ /* B-AX. THE VALUES -1, 0, OR 1 FOR RES(I) */ /* INDICATE THAT THE I-TH RESIDUAL (1.LE.I.LE.K) IS */ /* RESTRICTED TO BE .LE.0, UNRESTRICTED, OR .GE.0 */ /* RESPECTIVELY. */ /* ERROR ON EXIT, THIS GIVES THE MINIMUM SUM OF */ /* ABSOLUTE VALUES OF THE RESIDUALS. */ /* CU A TWO DIMENSIONAL REAL ARRAY WITH TWO ROWS AND */ /* AT LEAST NKLMD COLUMNS USED FOR WORKSPACE. */ /* IU A TWO DIMENSIONAL INTEGER ARRAY WITH TWO ROWS AND */ /* AT LEAST NKLMD COLUMNS USED FOR WORKSPACE. */ /* S INTEGER ARRAY OF SIZE AT LEAST KLMD, USED FOR */ /* WORKSPACE. */ /* DOUBLE PRECISION DBLE */ /* REAL */ /* INITIALIZATION. */ if (svnid == NULL) fprintf (stderr, " "); /* * mp variables */ censor = 1; if (censor_arg == 0.0) censor = 0; mpf_set_default_prec (96); mpf_init (zero); mpf_init (dummy); mpf_init (dummy1); mpf_init_set_d (censor_tol, censor_arg); q = (mpf_t *) PHRQ_malloc ((size_t) (max_row_count * max_column_count * sizeof (mpf_t))); if (q == NULL) malloc_error (); for (i = 0; i < max_row_count * max_column_count; i++) { mpf_init_set_d (q[i], q_arg[i]); if (censor == 1) { if (mpf_cmp (q[i], zero) != 0) { mpf_abs (dummy1, q[i]); if (mpf_cmp (dummy1, censor_tol) <= 0) { mpf_set_si (q[i], 0); } } } } x = (mpf_t *) PHRQ_malloc ((size_t) (n2d * sizeof (mpf_t))); if (x == NULL) malloc_error (); for (i = 0; i < n2d; i++) { mpf_init_set_d (x[i], x_arg[i]); } res = (mpf_t *) PHRQ_malloc ((size_t) ((k + l + m) * sizeof (mpf_t))); if (res == NULL) malloc_error (); for (i = 0; i < k + l + m; i++) { mpf_init_set_d (res[i], res_arg[i]); } cu = (mpf_t *) PHRQ_malloc ((size_t) (2 * nklmd * sizeof (mpf_t))); if (cu == NULL) malloc_error (); for (i = 0; i < 2 * nklmd; i++) { mpf_init_set_d (cu[i], cu_arg[i]); } kode = (int *) PHRQ_malloc (sizeof (int)); if (kode == NULL) malloc_error (); *kode = *kode_arg; mpf_init (sum); mpf_init (error); mpf_init (z); mpf_init (zu); mpf_init (zv); mpf_init (xmax); mpf_init_set_si (minus_one, -1); mpf_init_set_d (toler, toler_arg); mpf_init_set_d (check_toler, toler_arg); mpf_init (pivot); mpf_init (xmin); mpf_init (cuv); mpf_init (tpivot); mpf_init (sn); /* Parameter adjustments */ q_dim = n2d; q2 = (union double_or_int *) q; cu_dim = nklmd; /* Function Body */ maxit = *iter; n1 = n + 1; n2 = n + 2; nk = n + k; nkl = nk + l; klm = k + l + m; klm1 = klm + 1; nklm = n + klm; kforce = 1; *iter = 0; js = 0; ia = -1; /* Make scratch space */ /* scratch = (LDBLE *) PHRQ_malloc( (size_t) nklmd * sizeof(LDBLE)); if (scratch == NULL) malloc_error(); for (i=0; i < nklmd; i++) { scratch[i] = 0.0; } */ /* scratch = (mpf_t *) PHRQ_malloc( (size_t) nklmd * sizeof(mpf_t)); if (scratch == NULL) malloc_error(); for (i=0; i < nklmd; i++) { mpf_init(scratch[i]); } */ /* SET UP LABELS IN Q. */ for (j = 0; j < n; ++j) { q2[klm1 * q_dim + j].ival = j + 1; } /* L10: */ for (i = 0; i < klm; ++i) { q2[i * q_dim + n1].ival = n + i + 1; if (mpf_cmp_d (q2[i * q_dim + n].dval, 0.0) < 0) { for (j = 0; j < n1; ++j) { /* q2[ i * q_dim + j ].dval = -q2[ i * q_dim + j ].dval; */ mpf_neg (q2[i * q_dim + j].dval, q2[i * q_dim + j].dval); } q2[i * q_dim + n1].ival = -q2[i * q_dim + n1].ival; /* L20: */ } } /* L30: */ /* SET UP PHASE 1 COSTS. */ iphase = 2; #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "Set up phase 1 costs\n"); #endif /* Zero first row of cu and iu */ /*memcpy( (void *) &(cu[0]), (void *) &(scratch[0]), (size_t) nklm * sizeof(mpf_t) ); */ for (j = 0; j < nklm; ++j) { mpf_set_si (cu[j], 0); iu[j] = 0; } /* L40: */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L40\n"); #endif if (l != 0) { for (j = nk; j < nkl; ++j) { mpf_set_si (cu[j], 1); /*cu[ j ] = 1.; */ iu[j] = 1; } /* L50: */ iphase = 1; } /* Copy first row of cu and iu to second row */ /*memcpy( (void *) &(cu[cu_dim]), (void *) &(cu[0]), (size_t) nklm * sizeof(mpf_t) ); */ for (i = 0; i < nklm; i++) { mpf_set (cu[cu_dim + i], cu[i]); } memcpy ((void *) &(iu[cu_dim]), (void *) &(iu[0]), (size_t) nklm * sizeof (int)); /* L60: */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L60\n"); #endif if (m != 0) { for (j = nkl; j < nklm; ++j) { /* cu[ cu_dim + j ] = 1.; */ mpf_set_si (cu[cu_dim + j], 1); iu[cu_dim + j] = 1; jmn = j - n; if (q2[jmn * q_dim + n1].ival < 0) { iphase = 1; } } /* L70: */ } /* L80: */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L80\n"); #endif if (*kode != 0) { for (j = 0; j < n; ++j) { /* if ( x[j] < 0.) { */ if (mpf_cmp_si (x[j], 0) < 0) { /* L90: */ /* cu[ j ] = 1.; */ mpf_set_si (cu[j], 1); iu[j] = 1; /* } else if (x[j] > 0.) { */ } else if (mpf_cmp_si (x[j], 0) > 0) { /* cu[ cu_dim + j ] = 1.; */ mpf_set_si (cu[cu_dim + j], 1); iu[cu_dim + j] = 1; } } /* L110: */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L110\n"); #endif for (j = 0; j < k; ++j) { jpn = j + n; /* if (res[j] < 0.) { */ if (mpf_cmp_si (res[j], 0) < 0) { /* L120: */ /* cu[ jpn ] = 1.; */ mpf_set_si (cu[jpn], 1); iu[jpn] = 1; if (q2[j * q_dim + n1].ival > 0) { iphase = 1; } /* } else if (res[j] > 0.) { */ } else if (mpf_cmp_si (res[j], 0) > 0) { /* L130: */ /* cu[ cu_dim + jpn ] = 1.; */ mpf_set_si (cu[cu_dim + jpn], 1); iu[cu_dim + jpn] = 1; if (q2[j * q_dim + n1].ival < 0) { iphase = 1; } } } /* L140: */ } /* L150: */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L150\n"); #endif if (iphase == 2) { goto L500; } /* COMPUTE THE MARGINAL COSTS. */ L160: #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L160\n"); #endif for (j = js; j < n1; ++j) { mpf_set_si (sum, 0); for (i = 0; i < klm; ++i) { ii = q2[i * q_dim + n1].ival; if (ii < 0) { /* z = cu[ cu_dim - ii - 1 ]; */ mpf_set (z, cu[cu_dim - ii - 1]); } else { /*z = cu[ ii - 1 ]; */ mpf_set (z, cu[ii - 1]); } /*sum += q2[ i * q_dim + j ].dval * z; */ mpf_mul (dummy, q2[i * q_dim + j].dval, z); mpf_add (sum, sum, dummy); } /*q2[ klm * q_dim + j ].dval = sum; */ mpf_set (q2[klm * q_dim + j].dval, sum); } for (j = js; j < n; ++j) { ii = q2[klm1 * q_dim + j].ival; if (ii < 0) { /*z = cu[ cu_dim - ii - 1 ]; */ mpf_set (z, cu[cu_dim - ii - 1]); } else { /*z = cu[ ii - 1 ]; */ mpf_set (z, cu[ii - 1]); } /*q2[ klm * q_dim + j ].dval -= z; */ mpf_sub (q2[klm * q_dim + j].dval, q2[klm * q_dim + j].dval, z); } /* DETERMINE THE VECTOR TO ENTER THE BASIS. */ L240: #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L240, xmax %e\n", mpf_get_d (xmax)); #endif /*xmax = 0.; */ mpf_set_si (xmax, 0); if (js >= n) { goto L490; /* test for optimality */ } for (j = js; j < n; ++j) { /*zu = q2[ klm * q_dim + j ].dval; */ mpf_set (zu, q2[klm * q_dim + j].dval); ii = q2[klm1 * q_dim + j].ival; if (ii > 0) { /*zv = -zu - cu[ ii - 1 ] - cu[ cu_dim + ii - 1 ]; */ mpf_mul (dummy, cu[cu_dim + ii - 1], minus_one); mpf_sub (dummy, dummy, cu[ii - 1]); mpf_sub (zv, dummy, zu); } else { ii = -ii; /* zv = zu; */ mpf_set (zv, zu); /* zu = -zu - cu[ ii - 1 ] - cu[ cu_dim + ii - 1 ]; */ mpf_mul (dummy, cu[cu_dim + ii - 1], minus_one); mpf_sub (dummy, dummy, cu[ii - 1]); mpf_sub (zu, dummy, zu); } /* L260 */ if (kforce == 1 && ii > n) { continue; } /*if (iu[ ii - 1 ] != 1 && zu > xmax){ */ if ((iu[ii - 1] != 1) && (mpf_cmp (zu, xmax) > 0)) { /*xmax = zu; */ mpf_set (xmax, zu); in = j; } /* L270 */ /*if (iu[ cu_dim + ii - 1 ] != 1 && zv > xmax ) { */ if ((iu[cu_dim + ii - 1] != 1) && (mpf_cmp (zv, xmax) > 0)) { /*xmax = zv; */ mpf_set (xmax, zv); in = j; } } /* L280 */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L280 xmax %e, toler %e\n", mpf_get_d (xmax), mpf_get_d (toler)); #endif /*if (xmax <= toler) { */ if (mpf_cmp (xmax, toler) <= 0) { #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "xmax before optimality test %e\n", mpf_get_d (xmax)); #endif goto L490; /* test for optimality */ } /*if (q2[ klm * q_dim + in ].dval != xmax) { */ if (mpf_cmp (q2[klm * q_dim + in].dval, xmax) != 0) { for (i = 0; i < klm1; ++i) { /*q2[ i * q_dim + in ].dval = -q2[ i * q_dim + in ].dval; */ mpf_neg (q2[i * q_dim + in].dval, q2[i * q_dim + in].dval); } q2[klm1 * q_dim + in].ival = -q2[klm1 * q_dim + in].ival; /* L290: */ /*q2[ klm * q_dim + in ].dval = xmax; */ mpf_set (q2[klm * q_dim + in].dval, xmax); } /* DETERMINE THE VECTOR TO LEAVE THE BASIS. */ if (iphase != 1 && ia != -1) { /*xmax = 0.; */ mpf_set_si (xmax, 0); /* find maximum absolute value in column "in" */ for (i = 0; i <= ia; ++i) { /*z = fabs(q2[ i * q_dim + in ].dval); */ mpf_abs (z, q2[i * q_dim + in].dval); /*if (z > xmax) { */ if (mpf_cmp (z, xmax) > 0) { /*xmax = z; */ mpf_set (xmax, z); iout = i; } } /* L310: */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L310, xmax %e\n", mpf_get_d (xmax)); #endif /* switch row ia with row iout, use memcpy */ /*if (xmax > toler) { */ if (mpf_cmp (xmax, toler) > 0) { /* memcpy( (void *) &(scratch[0]), (void *) &(q2[ ia * q_dim]), (size_t) n2 * sizeof(mpf_t) ); memcpy( (void *) &(q2[ ia * q_dim ]), (void *) &(q2[ iout * q_dim]), (size_t) n2 * sizeof(mpf_t) ); memcpy( (void *) &(q2[ iout * q_dim ]), (void *) &(scratch[ 0 ]), (size_t) n2 * sizeof(mpf_t) ); */ for (i = 0; i < n1; i++) { mpf_set (dummy, q2[ia * q_dim + i].dval); mpf_set (q2[ia * q_dim + i].dval, q2[iout * q_dim + i].dval); mpf_set (q2[iout * q_dim + i].dval, dummy); } j = q2[ia * q_dim + n1].ival; q2[ia * q_dim + n1].ival = q2[iout * q_dim + n1].ival; q2[iout * q_dim + n1].ival = j; /* L320: */ /* set pivot to row ia, column in */ iout = ia; --ia; /*pivot = q2[ iout * q_dim + in ].dval; */ mpf_set (pivot, q2[iout * q_dim + in].dval); goto L420; /* Gauss Jordan */ } } /* L330: */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L330, xmax %e\n", mpf_get_d (xmax)); #endif kk = -1; /* divide column n1 by positive value in column "in" greater than toler */ for (i = 0; i < klm; ++i) { /*z = q2[ i * q_dim + in ].dval; */ mpf_set (z, q2[i * q_dim + in].dval); /*if (z > toler) { */ if (mpf_cmp (z, toler) > 0) { ++kk; /*res[kk] = q2[ i * q_dim + n ].dval / z; */ mpf_div (res[kk], q2[i * q_dim + n].dval, z); s[kk] = i; } } /* L340: */ if (kk < 0) { output_msg (OUTPUT_MESSAGE, "kode = 2 in loop 340.\n"); } L350: #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L350, xmax %e\n", mpf_get_d (xmax)); #endif if (kk < 0) { /* no positive value found in L340 or bypass intermediate verticies */ *kode = 2; goto L590; } /* L360: */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L360, xmax %e\n", mpf_get_d (xmax)); #endif /* find minimum residual */ /*xmin = res[ 0 ]; */ mpf_set (xmin, res[0]); iout = s[0]; j = 0; if (kk != 0) { for (i = 1; i <= kk; ++i) { /*if (res[i] < xmin) { */ if (mpf_cmp (res[i], xmin) < 0) { j = i; /*xmin = res[i]; */ mpf_set (xmin, res[i]); iout = s[i]; } } /* L370: */ /* put kk in position j */ /*res[j] = res[kk]; */ mpf_set (res[j], res[kk]); s[j] = s[kk]; } /* L380: */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L380 iout %d, xmin %e, xmax %e\n", iout, mpf_get_d (xmin), mpf_get_d (xmax)); #endif --kk; /*pivot = q2[ iout * q_dim + in ].dval; */ mpf_set (pivot, q2[iout * q_dim + in].dval); ii = q2[iout * q_dim + n1].ival; if (iphase != 1) { if (ii < 0) { /* L390: */ if (iu[-ii - 1] == 1) { goto L420; } } else { if (iu[cu_dim + ii - 1] == 1) { goto L420; } } } /* L400: */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L400\n"); #endif ii = abs (ii); /*cuv = cu[ ii - 1 ] + cu[ cu_dim + ii - 1]; */ mpf_add (cuv, cu[ii - 1], cu[cu_dim + ii - 1]); /*if (q2[ klm * q_dim + in ].dval - pivot * cuv > toler) { */ mpf_mul (dummy, pivot, cuv); mpf_sub (dummy, q2[klm * q_dim + in].dval, dummy); if (mpf_cmp (dummy, toler) > 0) { /* BYPASS INTERMEDIATE VERTICES. */ for (j = js; j < n1; ++j) { /*z = q2[ iout * q_dim + j ].dval; */ mpf_set (z, q2[iout * q_dim + j].dval); /*q2[ klm * q_dim + j ].dval -= z * cuv; */ mpf_mul (dummy1, z, cuv); mpf_sub (q2[klm * q_dim + j].dval, q2[klm * q_dim + j].dval, dummy1); if (censor == 1) { if (mpf_cmp (q2[klm * q_dim + j].dval, zero) != 0) { mpf_abs (dummy1, q2[klm * q_dim + j].dval); if (mpf_cmp (dummy1, censor_tol) <= 0) { mpf_set_si (q2[klm * q_dim + j].dval, 0); } } } /*q2[ iout * q_dim + j ].dval = -z; */ mpf_neg (q2[iout * q_dim + j].dval, z); } /* L410: */ q2[iout * q_dim + n1].ival = -q2[iout * q_dim + n1].ival; goto L350; } /* GAUSS-JORDAN ELIMINATION. */ L420: #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "Gauss Jordon %d\n", *iter); #endif if (*iter >= maxit) { *kode = 3; goto L590; } /* L430: */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L430\n"); #endif ++(*iter); for (j = js; j < n1; ++j) { if (j != in) { /*q2[ iout * q_dim + j ].dval /= pivot; */ mpf_div (q2[iout * q_dim + j].dval, q2[iout * q_dim + j].dval, pivot); } } /* L440: */ for (j = js; j < n1; ++j) { if (j != in) { /*z = -q2[ iout * q_dim + j ].dval; */ mpf_neg (z, q2[iout * q_dim + j].dval); for (i = 0; i < klm1; ++i) { if (i != iout) { /*q2[ i * q_dim + j ].dval += z * q2[ i * q_dim + in ].dval; */ mpf_mul (dummy, z, q2[i * q_dim + in].dval); mpf_add (q2[i * q_dim + j].dval, q2[i * q_dim + j].dval, dummy); if (censor == 1) { if (mpf_cmp (q2[i * q_dim + j].dval, zero) != 0) { mpf_abs (dummy1, q2[i * q_dim + j].dval); if (mpf_cmp (dummy1, censor_tol) <= 0) { mpf_set_si (q2[i * q_dim + j].dval, 0); } } } } } /* L450: */ } } /* L460: */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L460\n"); #endif /*tpivot = -pivot; */ mpf_neg (tpivot, pivot); for (i = 0; i < klm1; ++i) { if (i != iout) { /*q2[ i * q_dim + in ].dval /= tpivot; */ mpf_div (q2[i * q_dim + in].dval, q2[i * q_dim + in].dval, tpivot); } } /* L470: */ /*q2[ iout * q_dim + in ].dval = 1. / pivot; */ mpf_set_si (dummy, 1); mpf_div (q2[iout * q_dim + in].dval, dummy, pivot); ii = q2[iout * q_dim + n1].ival; q2[iout * q_dim + n1].ival = q2[klm1 * q_dim + in].ival; q2[klm1 * q_dim + in].ival = ii; ii = abs (ii); if (iu[ii - 1] == 0 || iu[cu_dim + ii - 1] == 0) { goto L240; } /* switch column */ for (i = 0; i < klm1; ++i) { /*z = q2[ i * q_dim + in ].dval; */ mpf_set (z, q2[i * q_dim + in].dval); /*q2[ i * q_dim + in ].dval = q2[ i * q_dim + js ].dval; */ mpf_set (q2[i * q_dim + in].dval, q2[i * q_dim + js].dval); /*q2[ i * q_dim + js ].dval = z; */ mpf_set (q2[i * q_dim + js].dval, z); } i = q2[klm1 * q_dim + in].ival; q2[klm1 * q_dim + in].ival = q2[klm1 * q_dim + js].ival; q2[klm1 * q_dim + js].ival = i; /* L480: */ ++js; goto L240; /* TEST FOR OPTIMALITY. */ L490: #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L490\n"); #endif if (kforce == 0) { if (iphase == 1) { /*if (q2[ klm * q_dim + n ].dval <= toler) { */ if (mpf_cmp (q2[klm * q_dim + n].dval, toler) <= 0) { goto L500; } #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "q2[klm1-1, n1-1] > *toler. %e\n", mpf_get_d (q2[(klm1 - 1) * q_dim + n1 - 1].dval)); #endif *kode = 1; goto L590; } *kode = 0; goto L590; } /*if (iphase != 1 || q2[ klm * q_dim + n ].dval > toler) { */ if ((iphase != 1) || (mpf_cmp (q2[klm * q_dim + n].dval, toler) > 0)) { kforce = 0; goto L240; } /* SET UP PHASE 2 COSTS. */ L500: #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "Set up phase 2 costs %d\n", *iter); #endif iphase = 2; for (j = 0; j < nklm; ++j) { /*cu[ j ] = 0.; */ mpf_set_si (cu[j], 0); } /* L510: */ for (j = n; j < nk; ++j) { /*cu[ j ] = 1.; */ mpf_set_si (cu[j], 1); } /* memcpy( (void *) &(cu[cu_dim]), (void *) &(cu[0]), (size_t) nklm * sizeof(LDBLE) ); */ for (i = 0; i < nklm; i++) { mpf_set (cu[cu_dim + i], cu[i]); } /* L520: */ for (i = 0; i < klm; ++i) { ii = q2[i * q_dim + n1].ival; if (ii <= 0) { if (iu[cu_dim - ii - 1] == 0) { continue; } /*cu[ cu_dim - ii - 1 ] = 0.; */ mpf_set_si (cu[cu_dim - ii - 1], 0); } else { /* L530: */ if (iu[ii - 1] == 0) { continue; } /*cu[ ii - 1 ] = 0.; */ mpf_set_si (cu[ii - 1], 0); } /* L540: */ ++ia; /* switch row */ /* memcpy( (void *) &(scratch[0]), (void *) &(q2[ ia * q_dim]), (size_t) n2 * sizeof(LDBLE) ); memcpy( (void *) &(q2[ ia * q_dim ]), (void *) &(q2[ i * q_dim]), (size_t) n2 * sizeof(LDBLE) ); memcpy( (void *) &(q2[ i * q_dim ]), (void *) &(scratch[ 0 ]), (size_t) n2 * sizeof(LDBLE) ); */ for (iswitch = 0; iswitch < n1; iswitch++) { mpf_set (dummy, q2[ia * q_dim + iswitch].dval); mpf_set (q2[ia * q_dim + iswitch].dval, q2[i * q_dim + iswitch].dval); mpf_set (q2[i * q_dim + iswitch].dval, dummy); } iswitch = q2[ia * q_dim + n1].ival; q2[ia * q_dim + n1].ival = q2[i * q_dim + n1].ival; q2[i * q_dim + n1].ival = iswitch; /* L550: */ } /* L560: */ goto L160; /* PREPARE OUTPUT. */ L590: #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L590\n"); #endif /*sum = 0.; */ mpf_set_si (sum, 0); for (j = 0; j < n; ++j) { /*x[j] = 0.; */ mpf_set_si (x[j], 0); } /* L600: */ for (i = 0; i < klm; ++i) { /*res[i] = 0.; */ mpf_set_si (res[i], 0); } /* L610: */ for (i = 0; i < klm; ++i) { ii = q2[i * q_dim + n1].ival; /*sn = 1.; */ mpf_set_si (sn, 1); if (ii < 0) { ii = -ii; /*sn = -1.; */ mpf_set_si (sn, -1); } if (ii <= n) { /* L620: */ /*x[ii - 1] = sn * q2[ i * q_dim + n ].dval; */ mpf_mul (x[ii - 1], sn, q2[i * q_dim + n].dval); } else { /* L630: */ /*res[ii - n - 1] = sn * q2[ i * q_dim + n ].dval; */ mpf_mul (res[ii - n - 1], sn, q2[i * q_dim + n].dval); if (ii >= n1 && ii <= nk) { /* * DBLE(Q(I,N1)) */ /*sum += q2[ i * q_dim + n ].dval; */ mpf_add (sum, sum, q2[i * q_dim + n].dval); } } } /* L640: */ #ifdef DEBUG_CL1 output_msg (OUTPUT_MESSAGE, "L640\n"); #endif /* * Check calculation */ mpf_set_si (dummy, 100); mpf_mul (check_toler, toler, dummy); if (check && *kode == 0) { /* * Check optimization constraints */ if (*kode_arg == 1) { for (i = 0; i < k; i++) { if (res_arg[i] < 0.0) { mpf_sub (dummy, res[i], check_toler); mpf_set_si (dummy1, 0); if (mpf_cmp (dummy, dummy1) > 0) { #ifdef CHECK_ERRORS output_msg (OUTPUT_MESSAGE, "\tCL1MP: optimization constraint not satisfied row %d, res %e, constraint %f.\n", i, mpf_get_d (res[i]), res_arg[i]); #endif *kode = 1; } } else if (res_arg[i] > 0.0) { mpf_add (dummy, res[i], check_toler); mpf_set_si (dummy1, 0); if (mpf_cmp (dummy, dummy1) < 0) { #ifdef CHECK_ERRORS output_msg (OUTPUT_MESSAGE, "\tCL1MP: optimization constraint not satisfied row %d, res %e, constraint %f.\n", i, mpf_get_d (res[i]), res_arg[i]); #endif *kode = 1; } } } } /* * Check equalities */ for (i = k; i < k + l; i++) { mpf_abs (dummy, res[i]); if (mpf_cmp (dummy, check_toler) > 0) { #ifdef CHECK_ERRORS output_msg (OUTPUT_MESSAGE, "\tCL1MP: equality constraint not satisfied row %d, res %e, tolerance %e.\n", i, mpf_get_d (res[i]), mpf_get_d (check_toler)); #endif *kode = 1; } } /* * Check inequalities */ for (i = k + l; i < k + l + m; i++) { mpf_neg (dummy, check_toler); if (mpf_cmp (res[i], dummy) < 0) { #ifdef CHECK_ERRORS output_msg (OUTPUT_MESSAGE, "\tCL1MP: inequality constraint not satisfied row %d, res %e, tolerance %e.\n", i, mpf_get_d (res[i]), mpf_get_d (check_toler)); #endif *kode = 1; } } /* * Check dissolution/precipitation constraints */ if (*kode_arg == 1) { for (i = 0; i < n; i++) { if (x_arg[i] < 0.0) { mpf_sub (dummy, x[i], check_toler); mpf_set_si (dummy1, 0); if (mpf_cmp (dummy, dummy1) > 0) { #ifdef CHECK_ERRORS output_msg (OUTPUT_MESSAGE, "\tCL1MP: dis/pre constraint not satisfied column %d, x %e, constraint %f.\n", i, mpf_get_d (x[i]), x_arg[i]); #endif *kode = 1; } } else if (x_arg[i] > 0.0) { mpf_add (dummy, x[i], check_toler); mpf_set_si (dummy1, 0); if (mpf_cmp (dummy, dummy1) < 0) { #ifdef CHECK_ERRORS output_msg (OUTPUT_MESSAGE, "\tCL1MP: dis/pre constraint not satisfied column %d, x %e, constraint %f.\n", i, mpf_get_d (x[i]), x_arg[i]); #endif *kode = 1; } } } } if (*kode == 1) { output_msg (OUTPUT_MESSAGE, "\n\tCL1MP: Roundoff errors in optimization.\n\t Deleting model.\n"); } } /* * set return variables */ /**error = sum;*/ mpf_set (error, sum); *error_arg = mpf_get_d (error); *kode_arg = *kode; for (i = 0; i < n2d; i++) { x_arg[i] = mpf_get_d (x[i]); } for (i = 0; i < k + l + m; i++) { res_arg[i] = mpf_get_d (res[i]); } /*scratch = free_check_null (scratch); */ for (i = 0; i < max_row_count * max_column_count; i++) { mpf_clear (q[i]); } q = (mpf_t *) free_check_null (q); for (i = 0; i < n2d; i++) { mpf_clear (x[i]); } x = (mpf_t *) free_check_null (x); for (i = 0; i < k + l + m; i++) { mpf_clear (res[i]); } res = (mpf_t *) free_check_null (res); for (i = 0; i < 2 * nklmd; i++) { mpf_clear (cu[i]); } cu = (mpf_t *) free_check_null (cu); mpf_clear (dummy); mpf_clear (dummy1); mpf_clear (sum); mpf_clear (error); mpf_clear (z); mpf_clear (zu); mpf_clear (zv); mpf_clear (xmax); mpf_clear (minus_one); mpf_clear (toler); mpf_clear (check_toler); mpf_clear (pivot); mpf_clear (xmin); mpf_clear (cuv); mpf_clear (tpivot); mpf_clear (sn); mpf_clear (censor_tol); kode = (int *) free_check_null (kode); return 0; }
/* * eval_mm_valid - Check the mm malloc package for correctness */ static int eval_mm_valid(trace_t *trace, int tracenum, range_t **ranges) { int i, j; int index; int size; int oldsize; char *newp; char *oldp; char *p; /* Reset the heap and free any records in the range list */ mem_reset_brk(); clear_ranges(ranges); /* Call the mm package's init function */ if (mm_init() < 0) { malloc_error(tracenum, 0, "mm_init failed."); return 0; } /* Interpret each operation in the trace in order */ for (i = 0; i < trace->num_ops; i++) { index = trace->ops[i].index; size = trace->ops[i].size; switch (trace->ops[i].type) { case ALLOC: /* mm_malloc */ /* Call the student's malloc */ if ((p = mm_malloc(size)) == NULL) { malloc_error(tracenum, i, "mm_malloc failed."); return 0; } /* * Test the range of the new block for correctness and add it * to the range list if OK. The block must be be aligned properly, * and must not overlap any currently allocated block. */ if (add_range(ranges, p, size, tracenum, i) == 0) return 0; /* ADDED: cgw * fill range with low byte of index. This will be used later * if we realloc the block and wish to make sure that the old * data was copied to the new block */ memset(p, index & 0xFF, size); /* Remember region */ trace->blocks[index] = p; trace->block_sizes[index] = size; break; case REALLOC: /* mm_realloc */ /* Call the student's realloc */ oldp = trace->blocks[index]; if ((newp = mm_realloc(oldp, size)) == NULL) { malloc_error(tracenum, i, "mm_realloc failed."); return 0; } /* Remove the old region from the range list */ remove_range(ranges, oldp); /* Check new block for correctness and add it to range list */ if (add_range(ranges, newp, size, tracenum, i) == 0) return 0; /* ADDED: cgw * Make sure that the new block contains the data from the old * block and then fill in the new block with the low order byte * of the new index */ oldsize = trace->block_sizes[index]; if (size < oldsize) oldsize = size; for (j = 0; j < oldsize; j++) { if (newp[j] != (index & 0xFF)) { malloc_error(tracenum, i, "mm_realloc did not preserve the " "data from old block"); return 0; } } memset(newp, index & 0xFF, size); /* Remember region */ trace->blocks[index] = newp; trace->block_sizes[index] = size; break; case FREE: /* mm_free */ /* Remove region from list and call student's free function */ p = trace->blocks[index]; remove_range(ranges, p); mm_free(p); break; default: app_error("Nonexistent request type in eval_mm_valid"); } } /* As far as we know, this is a valid malloc package */ return 1; }
/* ---------------------------------------------------------------------- */ int P_step (LDBLE step_fraction) /* ---------------------------------------------------------------------- */ { /* * zero global solution, add solution or mixture, add exchange, * add surface, add gas phase, add solid solutions, * set temperature, and add reaction. * Ensure all elements * included in any of these are present in small amounts. * Save result as n_user -1. */ LDBLE difftemp; int step_number; struct pp_assemblage *pp_assemblage_save = NULL; struct s_s_assemblage *s_s_assemblage_save = NULL; if (svnid == NULL) fprintf (stderr, " "); /* * Zero out global solution data */ xsolution_zero (); /* * Set reaction to zero */ step_x = 0.0; step_number = reaction_step; /* * Mixing or solution */ if (use.mix_ptr != NULL) { add_mix (use.mix_ptr); } else if (use.solution_ptr != NULL) { add_solution (use.solution_ptr, 1.0, 1.0); } else { input_error++; error_msg ("Neither mixing nor an initial solution have " "been defined in reaction step.", STOP); } /* * Reaction */ if (use.irrev_ptr != NULL) { add_reaction (use.irrev_ptr, step_number, step_fraction); } /* * Kinetics */ if (use.kinetics_ptr != NULL) { add_kinetics (use.kinetics_ptr); /* master_ptr =master_bsearch("S(6)"); output_msg(OUTPUT_MESSAGE,"Added kinetics, S(6) %e\n", master_ptr->total); master_ptr =master_bsearch("S"); output_msg(OUTPUT_MESSAGE,"Added kinetics, S %e\n", master_ptr->total); */ } /* * Exchange */ if (use.exchange_ptr != NULL) { add_exchange (use.exchange_ptr); } /* * Surface */ if (use.surface_ptr != NULL) { add_surface (use.surface_ptr); } /* * Gases */ if (use.gas_phase_ptr != NULL) { add_gas_phase (use.gas_phase_ptr); } /* * Temperature */ if (use.temperature_ptr != NULL) { add_temperature (use.temperature_ptr, step_number); } if ((state == TRANSPORT) && (transport_step != 0) && (cell > 0) && (cell != count_cells + 1)) { difftemp = tc_x - cell_data[cell - 1].temp; cell_data[cell - 1].temp += difftemp / tempr; tc_x = cell_data[cell - 1].temp; } /* * Pure phases and solid solutions are added to avoid * zero or negative concentrations */ /* * Pure phases */ if (use.pp_assemblage_ptr != NULL) { pp_assemblage_save = (struct pp_assemblage *) PHRQ_malloc (sizeof (struct pp_assemblage)); if (pp_assemblage_save == NULL) malloc_error (); pp_assemblage_copy (use.pp_assemblage_ptr, pp_assemblage_save, use.pp_assemblage_ptr->n_user); add_pp_assemblage (use.pp_assemblage_ptr); } /* * Solid solutions */ if (use.s_s_assemblage_ptr != NULL) { s_s_assemblage_save = (struct s_s_assemblage *) PHRQ_malloc (sizeof (struct s_s_assemblage)); if (s_s_assemblage_save == NULL) malloc_error (); s_s_assemblage_copy (use.s_s_assemblage_ptr, s_s_assemblage_save, use.s_s_assemblage_ptr->n_user); add_s_s_assemblage (use.s_s_assemblage_ptr); } /* * Check that elements are available for gas components, * pure phases, and solid solutions */ if (use.gas_phase_ptr != NULL) { gas_phase_check (use.gas_phase_ptr); } if (use.pp_assemblage_ptr != NULL) { pp_assemblage_check (use.pp_assemblage_ptr); } if (use.s_s_assemblage_ptr != NULL) { s_s_assemblage_check (use.s_s_assemblage_ptr); } /* * Check that element moles are >= zero */ if (solution_check () == MASS_BALANCE) { /* reset moles and deltas */ if (use.pp_assemblage_ptr != NULL) { pp_assemblage_free (use.pp_assemblage_ptr); pp_assemblage_copy (pp_assemblage_save, use.pp_assemblage_ptr, use.pp_assemblage_ptr->n_user); pp_assemblage_free (pp_assemblage_save); pp_assemblage_save = (struct pp_assemblage *) free_check_null (pp_assemblage_save); } if (use.s_s_assemblage_ptr != NULL) { s_s_assemblage_free (use.s_s_assemblage_ptr); s_s_assemblage_copy (s_s_assemblage_save, use.s_s_assemblage_ptr, use.s_s_assemblage_ptr->n_user); s_s_assemblage_free (s_s_assemblage_save); s_s_assemblage_save = (struct s_s_assemblage *) free_check_null (s_s_assemblage_save); } return (MASS_BALANCE); } /* * Copy global into solution n_user = -1 */ xsolution_save (-1); step_save_surf (-1); step_save_exch (-1); /* * Clean up temporary space */ if (pp_assemblage_save != NULL) { pp_assemblage_free (pp_assemblage_save); pp_assemblage_save = (struct pp_assemblage *) free_check_null (pp_assemblage_save); } if (s_s_assemblage_save != NULL) { s_s_assemblage_free (s_s_assemblage_save); s_s_assemblage_save = (struct s_s_assemblage *) free_check_null (s_s_assemblage_save); } return (OK); }
/* ---------------------------------------------------------------------- */ struct spread_row * string_to_spread_row (char *string) /* ---------------------------------------------------------------------- */ { int j, l; static int length = 10; /* possible memory error if length of line is smaller than previous line */ char *token; char *ptr; struct spread_row *spread_row_ptr; /* * Allocate space */ token = (char *) PHRQ_malloc (strlen(line)+1); if (token == NULL) malloc_error (); spread_row_ptr = (struct spread_row *) PHRQ_malloc ((size_t) sizeof (struct spread_row)); if (spread_row_ptr == NULL) malloc_error (); spread_row_ptr->char_vector = (char **) PHRQ_malloc ((size_t) length * sizeof (char *)); if (spread_row_ptr->char_vector == NULL) malloc_error (); spread_row_ptr->d_vector = (LDBLE *) PHRQ_malloc ((size_t) length * sizeof (LDBLE)); if (spread_row_ptr->d_vector == NULL) malloc_error (); spread_row_ptr->type_vector = (int *) PHRQ_malloc ((size_t) length * sizeof (int)); if (spread_row_ptr->type_vector == NULL) malloc_error (); spread_row_ptr->count = 0; spread_row_ptr->empty = 0; spread_row_ptr->string = 0; spread_row_ptr->number = 0; ptr = string; /* * Split by tabs, reallocate space */ for (;;) { if (spread_row_ptr->count + 1 > length) { length *= 2; spread_row_ptr->char_vector = (char **) PHRQ_realloc (spread_row_ptr->char_vector, (size_t) length * sizeof (char *)); if (spread_row_ptr->char_vector == NULL) malloc_error (); spread_row_ptr->d_vector = (LDBLE *) PHRQ_realloc (spread_row_ptr->d_vector, (size_t) length * sizeof (LDBLE)); if (spread_row_ptr->d_vector == NULL) malloc_error (); spread_row_ptr->type_vector = (int *) PHRQ_realloc (spread_row_ptr->type_vector, (size_t) length * sizeof (int)); if (spread_row_ptr->type_vector == NULL) malloc_error (); } j = copy_token_tab (token, &ptr, &l); if (j == EOL) break; spread_row_ptr->char_vector[spread_row_ptr->count] = string_duplicate (token); spread_row_ptr->d_vector[spread_row_ptr->count] = NAN; if (j == EMPTY || l == 0) { spread_row_ptr->empty++; spread_row_ptr->type_vector[spread_row_ptr->count] = EMPTY; } else if (j == UPPER || j == LOWER) { spread_row_ptr->string++; spread_row_ptr->type_vector[spread_row_ptr->count] = STRING; } else if (j == DIGIT) { spread_row_ptr->number++; spread_row_ptr->d_vector[spread_row_ptr->count] = strtod (token, NULL); spread_row_ptr->type_vector[spread_row_ptr->count] = NUMBER; } spread_row_ptr->count++; } /* * Clean up and return */ if (spread_row_ptr->count == 0) { spread_row_ptr->char_vector = (char **) free_check_null (spread_row_ptr->char_vector); spread_row_ptr->d_vector = (LDBLE *) free_check_null (spread_row_ptr->d_vector); spread_row_ptr->type_vector = (int *) free_check_null (spread_row_ptr->type_vector); } else { /* Do not realloc to smaller size, memory error */ /* spread_row_ptr->char_vector = (char **) PHRQ_realloc (spread_row_ptr->char_vector, (size_t) spread_row_ptr->count * sizeof (char *)); if (spread_row_ptr->char_vector == NULL) malloc_error (); spread_row_ptr->d_vector = (LDBLE *) PHRQ_realloc (spread_row_ptr->d_vector, (size_t) spread_row_ptr->count * sizeof (LDBLE)); if (spread_row_ptr->d_vector == NULL) malloc_error (); spread_row_ptr->type_vector = (int *) PHRQ_realloc (spread_row_ptr->type_vector, (size_t) spread_row_ptr->count * sizeof (int)); if (spread_row_ptr->type_vector == NULL) malloc_error (); */ } token = (char *) free_check_null (token); return (spread_row_ptr); }
/* ---------------------------------------------------------------------- */ void polint (LDBLE * xa, LDBLE * ya, int n, LDBLE xv, LDBLE * yv, LDBLE * dy) /* ---------------------------------------------------------------------- */ { int i, m, ns; LDBLE den, dif, dift, ho, hp, w; LDBLE *c, *d; ns = 1; dif = fabs (xv - xa[1]); /* * Malloc work space */ c = (double *) PHRQ_malloc ((size_t) (n + 1) * sizeof (LDBLE)); if (c == NULL) malloc_error (); d = (double *) PHRQ_malloc ((size_t) (n + 1) * sizeof (LDBLE)); if (d == NULL) malloc_error (); for (i = 1; i <= n; i++) { dift = fabs (xv - xa[i]); if (dift < dif) { ns = i; dif = dift; } c[i] = ya[i]; d[i] = ya[i]; } *yv = ya[ns--]; for (m = 1; m < n; m++) { for (i = 1; i <= n - m; i++) { ho = xa[i] - xv; hp = xa[i + m] - xv; w = c[i + 1] - d[i]; if ((den = ho - hp) == 0.0) { error_msg ("In subroutine polint.", STOP); } den = w / den; d[i] = hp * den; c[i] = ho * den; } if (2 * ns < (n - m)) { *dy = c[ns + 1]; } else { *dy = d[ns--]; } *yv += *dy; /* *yv += (*dy = (2 * ns < (n-m) ? c[ns+1] : d[ns--])); */ } c = (double *) free_check_null (c); d = (double *) free_check_null (d); return; }
/* ---------------------------------------------------------------------- */ int calc_init_g (void) /* ---------------------------------------------------------------------- */ { int i, j, k; int count_g, count_charge; if (use.surface_ptr == NULL) return (OK); /* * calculate g for each surface */ count_charge = 0; for (j = 0; j < count_unknowns; j++) { if (x[j]->type != SURFACE_CB) continue; surface_charge_ptr = x[j]->surface_charge; count_g = 0; if (x[j]->surface_charge->g != NULL) { count_g = x[j]->surface_charge->count_g; } if (count_g == 0) { x[j]->surface_charge->g = (struct surface_diff_layer *) PHRQ_malloc ((size_t) sizeof (struct surface_diff_layer)); if (x[j]->surface_charge->g == NULL) malloc_error (); x[j]->surface_charge->g[0].charge = 0.0; x[j]->surface_charge->g[0].g = 0.0; x[j]->surface_charge->g[0].dg = 0.0; xd = exp (-2 * x[j]->master[0]->s->la * LOG_10); /* alpha = 0.02935 @ 25; (ee0RT/2)**1/2, (L/mol)**1/2 C / m**2 */ /* second 1000 is liters/m**3 */ alpha = sqrt (EPSILON * EPSILON_ZERO * (R_KJ_DEG_MOL * 1000.0) * 1000.0 * tk_x * 0.5); } /* * calculate g for given surface for each species */ count_g = 1; for (i = 0; i < count_s_x; i++) { if (s_x[i]->type > HPLUS) continue; for (k = 0; k < count_g; k++) { if (equal (x[j]->surface_charge->g[k].charge, s_x[i]->z, G_TOL) == TRUE) { s_x[i]->diff_layer[count_charge].charge = x[j]->surface_charge; s_x[i]->diff_layer[count_charge].count_g = k; s_x[i]->diff_layer[count_charge].g_moles = 0.0; s_x[i]->diff_layer[count_charge].dg_g_moles = 0.0; break; } } if (k >= count_g) { /* malloc space to save g for charge */ x[j]->surface_charge->g = (struct surface_diff_layer *) PHRQ_realloc (x[j]->surface_charge->g, (size_t) (count_g + 1) * sizeof (struct surface_diff_layer)); if (x[j]->surface_charge->g == NULL) malloc_error (); /* save g for charge */ x[j]->surface_charge->g[count_g].charge = s_x[i]->z; if (x[j]->surface_charge->grams > 0.0) { x[j]->surface_charge->g[count_g].g = 2 * alpha * sqrt (mu_x) * (pow (xd, s_x[i]->z / 2.0) - 1) * surface_charge_ptr->grams * surface_charge_ptr->specific_area / F_C_MOL; x[j]->surface_charge->g[count_g].dg = -s_x[i]->z; if ((use.surface_ptr->only_counter_ions == TRUE) && x[j]->surface_charge->g[count_g].g < 0) { x[j]->surface_charge->g[count_g].g = 0; x[j]->surface_charge->g[count_g].dg = 0; } } else { x[j]->surface_charge->g[count_g].g = 0.0; x[j]->surface_charge->g[count_g].dg = -s_x[i]->z; } /* save g for species */ s_x[i]->diff_layer[count_charge].charge = x[j]->surface_charge; s_x[i]->diff_layer[count_charge].count_g = count_g; s_x[i]->diff_layer[count_charge].g_moles = 0.0; s_x[i]->diff_layer[count_charge].dg_g_moles = 0.0; count_g++; } } if (debug_diffuse_layer == TRUE) { output_msg (OUTPUT_MESSAGE, "\nSurface component %d: charge,\tg,\tdg\n", count_charge); for (i = 0; i < count_g; i++) { output_msg (OUTPUT_MESSAGE, "\t%12f\t%12.4e\t%12.4e\n", (double) x[j]->surface_charge->g[i].charge, (double) x[j]->surface_charge->g[i].g, (double) x[j]->surface_charge->g[i].dg); } } count_charge++; x[j]->surface_charge->count_g = count_g; } return (OK); }
/* ---------------------------------------------------------------------- */ int calc_init_donnan (void) /* ---------------------------------------------------------------------- */ { int i, j, k; int count_g, count_charge; char name[MAX_LENGTH]; LDBLE f_psi, surf_chrg_eq, psi_avg, f_sinh, A_surf, ratio_aq; if (use.surface_ptr == NULL) return (OK); if (use.surface_ptr->type == CD_MUSIC) return (calc_init_donnan_music ()); f_sinh = sqrt (8000.0 * EPSILON * EPSILON_ZERO * (R_KJ_DEG_MOL * 1000.0) * tk_x * mu_x); if (convergence_tolerance >= 1e-8) { G_TOL = 1e-9; } else { G_TOL = 1e-13; } /* * sum eq of each charge number in solution... */ charge_group = (struct Charge_Group *) free_check_null (charge_group); charge_group = (struct Charge_Group *) PHRQ_malloc ((size_t) sizeof (struct Charge_Group)); if (charge_group == NULL) malloc_error (); charge_group[0].z = 0.0; charge_group[0].eq = 0.0; count_g = 1; for (i = 0; i < count_s_x; i++) { if (s_x[i]->type > HPLUS) continue; for (k = 0; k < count_g; k++) { if (equal (charge_group[k].z, s_x[i]->z, G_TOL) == TRUE) { charge_group[k].eq += s_x[i]->z * s_x[i]->moles; break; } } if (k >= count_g) { charge_group = (struct Charge_Group *) PHRQ_realloc (charge_group, (size_t) (count_g + 1) * sizeof (struct Charge_Group)); if (charge_group == NULL) malloc_error (); charge_group[count_g].z = s_x[i]->z; charge_group[count_g].eq = s_x[i]->z * s_x[i]->moles; count_g++; } } /* * calculate g for each surface... */ count_charge = 0; for (j = 0; j < count_unknowns; j++) { if (x[j]->type != SURFACE_CB) continue; surface_charge_ptr = x[j]->surface_charge; x[j]->surface_charge->g = (struct surface_diff_layer *) PHRQ_malloc ((size_t) count_g * sizeof (struct surface_diff_layer)); if (x[j]->surface_charge->g == NULL) malloc_error (); x[j]->surface_charge->count_g = count_g; /* find surface charge from potential... */ A_surf = x[j]->surface_charge->specific_area * x[j]->surface_charge->grams; f_psi = x[j]->master[0]->s->la * LOG_10; surf_chrg_eq = A_surf * f_sinh * sinh (f_psi) / F_C_MOL; /* find psi_avg that matches surface charge... */ psi_avg = calc_psi_avg (0); /*(surf_chrg_eq); */ /* fill in g's */ ratio_aq = surface_charge_ptr->mass_water / mass_water_aq_x; for (k = 0; k < count_g; k++) { x[j]->surface_charge->g[k].charge = charge_group[k].z; x[j]->surface_charge->g[k].g = ratio_aq * (exp (-charge_group[k].z * psi_avg) - 1); if (use.surface_ptr->only_counter_ions && ((surf_chrg_eq < 0 && charge_group[k].z < 0) || (surf_chrg_eq > 0 && charge_group[k].z > 0))) x[j]->surface_charge->g[k].g = -ratio_aq; if (x[j]->surface_charge->g[k].g != 0) { x[j]->surface_charge->g[k].dg = -A_surf * f_sinh * cosh (f_psi) / (charge_group[k].eq * F_C_MOL); } else { x[j]->surface_charge->g[k].dg = -charge_group[k].z; } /* save g for species */ for (i = 0; i < count_s_x; i++) { if (equal (charge_group[k].z, s_x[i]->z, G_TOL) == TRUE) { s_x[i]->diff_layer[count_charge].charge = x[j]->surface_charge; s_x[i]->diff_layer[count_charge].count_g = k; s_x[i]->diff_layer[count_charge].g_moles = 0.0; s_x[i]->diff_layer[count_charge].dg_g_moles = 0.0; } } } if (debug_diffuse_layer == TRUE) { strcpy (name, x[j]->master[0]->elt->name); replace ("_psi", "", name); /* surf_chrg_eq = calc_surface_charge(name); */ output_msg (OUTPUT_MESSAGE, "\nDonnan init on %s : charge, \tg, \tdg, Psi_surface = %8f V. \n", name, x[j]->master[0]->s->la * 2 * LOG_10 * R_KJ_DEG_MOL * tk_x / F_KJ_V_EQ); for (i = 0; i < count_g; i++) { output_msg (OUTPUT_MESSAGE, "\t%12f\t%12.4e\t%12.4e\n", (double) x[j]->surface_charge->g[i].charge, (double) x[j]->surface_charge->g[i].g, (double) x[j]->surface_charge->g[i].dg); } } count_charge++; } return (OK); }
/* Find the full pathname of a program. Code heavily based on * glibc-2.0.5/posix/execvp.c. */ char *find_fullpath(const char *program) { char *fullpath = NULL; char *path, *p; size_t len; static const char procname[] = "find_fullpath"; /* Don't search when it contains a slash. */ if (strchr(program, '/')) { if (!(fullpath = strdup(program))) malloc_error(procname); if (debug > 1) fprintf(stderr, "DEBUG: %s %s\n", procname, fullpath); return(fullpath); } path = getenv ("PATH"); if (!path) { /* There is no `PATH' in the environment. The default search path is the current directory followed by the path `confstr' returns for `_CS_PATH'. */ len = confstr(_CS_PATH, (char *) NULL, 0); if (!(path = malloc(1 + len))) malloc_error(procname); path[0] = ':'; confstr(_CS_PATH, path+1, len); } len = strlen(program) + 1; if (!(fullpath = malloc(strlen(path) + len))) malloc_error(procname); p = path; do { path = p; p = strchr(path, ':'); if (p == NULL) p = strchr(path, '\0'); /* Two adjacent colons, or a colon at the beginning or the end * of `PATH' means to search the current directory. */ if (p == path) memcpy(fullpath, program, len); else { /* Construct the pathname to try. */ memcpy(fullpath, path, p - path); fullpath[p - path] = '/'; memcpy(&fullpath[(p - path) + 1], program, len); } /* If we have execute access, assume this is the program. */ if (access(fullpath, X_OK) == 0) { if (debug > 1) fprintf(stderr, "DEBUG: %s %s\n", procname, fullpath); return(fullpath); } } while (*p++ != '\0'); fprintf(stderr, "Error: %s %s could not find executable %s\n", prefix, procname, program); ++errors; return(NULL); }