EDTree_t* operatorBEK(EDTree_t* root, char* variable) { assert(root != NULL && variable != NULL); assert(Tree_ok(root) == OK); EDTree_t* deriv = NULL; switch (root->type) { case NUMBER: deriv = Tree_construct(0, 0, NUMBER, NULL, NULL); break; case VARIABLE: if (strcmp(root->oper, variable) == 0) { deriv = Tree_construct(1, 0, NUMBER, NULL, NULL); } else { deriv = Tree_construct(0, 0, NUMBER, NULL, NULL); } break; case OPERATOR: if (root->oper[0] == '+' || root->oper[0] == '-') { deriv = Tree_construct(0, root->oper, OPERATOR, operatorBEK(root->left, variable), operatorBEK(root->right, variable)); break; } if (root->oper[0] == '*') { deriv = Tree_construct(0, "+", OPERATOR, Tree_construct(0, root->oper, OPERATOR, operatorBEK(root->left, variable), Tree_copy(root->right)), Tree_construct(0, root->oper, OPERATOR, Tree_copy(root->left), operatorBEK(root->right, variable))); } if (root->oper[0] == '/') { deriv = Tree_construct(0, root->oper, OPERATOR, Tree_construct(0, "-", OPERATOR, Tree_construct(0, "*", OPERATOR, operatorBEK(root->left, variable), Tree_copy(root->right)), Tree_construct(0, "*", OPERATOR, Tree_copy(root->left), operatorBEK(root->right, variable))), Tree_construct(0, "*", OPERATOR, Tree_copy(root->right), Tree_copy(root->right))); } break; case FUNCTION: if (strcmp(root->oper, "SIN") == 0) { deriv = Tree_construct(0, "*", OPERATOR, Tree_construct(0, "COS", FUNCTION, NULL, Tree_copy(root->right)), operatorBEK(root->right, variable)); } if (strcmp(root->oper, "COS") == 0) { deriv = Tree_construct(0, "*", OPERATOR, Tree_construct(0, "*", OPERATOR, Tree_construct(-1, 0, NUMBER, NULL, NULL), Tree_construct(0, "SIN", FUNCTION, NULL, Tree_copy(root->right))), operatorBEK(root->right, variable)); } if (strcmp(root->oper, "TAN") == 0) { deriv = Tree_construct(0, "*", OPERATOR, Tree_construct(0, "/", OPERATOR, Tree_construct(1, 0, NUMBER, NULL, NULL), Tree_construct(0, "*", OPERATOR, Tree_construct(0, "COS", FUNCTION, NULL, Tree_copy(root->right)), Tree_construct(0, "COS", FUNCTION, NULL, Tree_copy(root->right)))), operatorBEK(root->right, variable)); } if (strcmp(root->oper, "SQRT") == 0) { deriv = Tree_construct(0, "*", OPERATOR, Tree_construct(0, "/", OPERATOR, Tree_construct(1, 0, NUMBER, NULL, NULL), Tree_construct(0, "*", OPERATOR, Tree_construct(2, 0, NUMBER, NULL, NULL), Tree_construct(0, "SQRT", FUNCTION, NULL, Tree_copy(root->right)))), operatorBEK(root->right, variable)); } if (strcmp(root->oper, "LOG") == 0) { deriv = Tree_construct(0, "*", OPERATOR, Tree_construct(0, "/", OPERATOR, Tree_construct(1, 0, NUMBER, NULL, NULL), Tree_copy(root->right)), operatorBEK(root->right, variable)); } case END: break; default: printf("CHECK ITS.h\n"); break; } assert(Tree_ok(deriv) == OK); return deriv; }
EDTree_t* Tree_optimize (EDTree_t* root, int* isOptim) { //printf("IN Tree_optimize\n"); (*isOptim) = 1; EDTree_t* optim = NULL, *left = NULL, *right = NULL; if (root->left != NULL) left = Tree_optimize (root->left, isOptim); if ((*isOptim) == 0) { if (root->right != NULL) right = Tree_optimize (root->right, isOptim); (*isOptim) = 0; } else { if (root->right != NULL) right = Tree_optimize (root->right, isOptim); } switch (root->type) { case NUMBER: //printf("Optimize number %lg\n", root->number); optim = Tree_copy (root); break; case OPERATOR: switch (root->oper[0]) { case '+': //printf("Optimize +\n"); if (left->type == NUMBER && right->type == NUMBER) { optim = Tree_construct(left->number + right->number, 0, NUMBER, NULL, NULL); Tree_destruct(left); Tree_destruct(right); (*isOptim) = 0; } else { if (left->type == NUMBER && left->number == 0) { optim = right; Tree_destruct(left); (*isOptim) = 0; } else { if (right->type == NUMBER && right->number == 0) { optim = left; Tree_destruct(right); (*isOptim) = 0; } else { optim = Tree_construct(0, root->oper, OPERATOR, left, right); } } } break; case '-': //printf("Optimize -\n"); assert(left != NULL); assert(right != NULL); if (left->type == NUMBER && right->type == NUMBER) { //printf("Calc -\n"); optim = Tree_construct(left->number - right->number, 0, NUMBER, NULL, NULL); Tree_destruct(left); Tree_destruct(right); (*isOptim) = 0; } else { if (left->type == NUMBER && left->number == 0) { //printf("In - left->number == 0\n"); optim = Tree_construct(0, "*", OPERATOR, Tree_construct(-1, 0, NUMBER, NULL, NULL), right); Tree_destruct(left); (*isOptim) = 0; } else { if (right->type == NUMBER && right->number == 0) { //printf("In - right->number == 0\n"); optim = left; Tree_destruct(right); (*isOptim) = 0; } else { //printf("Not optimized -\n"); optim = Tree_construct(0, root->oper, OPERATOR, left, right); } } } break; case '*': //printf("Optimize *\n"); if (left->type == NUMBER && right->type == NUMBER) { //printf("%lg * %lg\n", left->number, right->number); optim = Tree_construct(left->number * right->number, 0, NUMBER, NULL, NULL); Tree_destruct(left); Tree_destruct(right); (*isOptim) = 0; } else { if (left->type == NUMBER) { if (left->number == 0) { //printf("left->number == 0\n"); optim = Tree_construct(0, 0, NUMBER, NULL, NULL); Tree_destruct(left); Tree_destruct(right); (*isOptim) = 0; } else { if (left->number == 1) { //printf("left->number == 1\n"); optim = right; Tree_destruct(left); (*isOptim) = 0; } else { //printf("Not optimizing *\n"); optim = Tree_construct(0, root->oper, OPERATOR, left, right); } } } else { if (right->type == NUMBER) { if (right->number == 0) { //printf("right->number == 0\n"); optim = Tree_construct(0, 0, NUMBER, NULL, NULL); Tree_destruct(left); Tree_destruct(right); (*isOptim) = 0; } else { if (right->number == 1) { //printf("right->number == 1\n"); optim = left; Tree_destruct(right); (*isOptim) = 0; } else { //printf("Not optimizing *\n"); optim = Tree_construct(0, root->oper, OPERATOR, left, right); } } } else { //printf("Not optimizing *\n"); optim = Tree_construct(0, root->oper, OPERATOR, left, right); } } } break; case '/': //printf("Optimize /\n"); if (left->type == NUMBER && right->type == NUMBER) { optim = Tree_construct(left->number / right->number, 0, NUMBER, NULL, NULL); Tree_destruct(left); Tree_destruct(right); (*isOptim) = 0; } else { if (left->type == NUMBER && left->number == 0) { optim = Tree_construct(0, 0, NUMBER, NULL, NULL); Tree_destruct(left); Tree_destruct(right); (*isOptim) = 0; } else { if (right->type == NUMBER && right->number == 1) { optim = left; Tree_destruct(right); (*isOptim) = 0; } else { optim = Tree_construct(0, root->oper, OPERATOR, left, right); } } } break; default: break; } break; case VARIABLE: //printf("Optimize VARIABLE\n"); optim = Tree_copy (root); break; case FUNCTION: //printf("Optimize FUNCTION\n"); if (right->type == NUMBER) { if (strcmp(root->oper, "SIN") == 0) { optim = Tree_construct(sin(right->number), 0, NUMBER, NULL, NULL); Tree_destruct(left); Tree_destruct(right); (*isOptim) = 0; } if (strcmp(root->oper, "COS") == 0) { optim = Tree_construct(cos(right->number), 0, NUMBER, NULL, NULL); Tree_destruct(left); Tree_destruct(right); (*isOptim) = 0; } if (strcmp(root->oper, "TAN") == 0) { optim = Tree_construct(tan(right->number), 0, NUMBER, NULL, NULL); Tree_destruct(left); Tree_destruct(right); (*isOptim) = 0; } if (strcmp(root->oper, "SQRT") == 0) { optim = Tree_construct(sqrt(right->number), 0, NUMBER, NULL, NULL); Tree_destruct(left); Tree_destruct(right); (*isOptim) = 0; } if (strcmp(root->oper, "LOG") == 0) { optim = Tree_construct(log(right->number), 0, NUMBER, NULL, NULL); Tree_destruct(left); Tree_destruct(right); (*isOptim) = 0; } } else { optim = Tree_construct(0, root->oper, FUNCTION, NULL, right); } break; case END: printf("WRONG TREE\n"); assert(1==0); break; default: printf("CHECK ITS.h\n"); assert(1==0); break; } return optim; }
int main(int argc, char **argv){ if(argc != 3) //check if there are enough input arguments { return EXIT_FAILURE; } FILE* input_file = fopen(argv[1],"r"); if(input_file == NULL){ return EXIT_FAILURE; } //get the input data int n_node; int n_block; char temp_char;//to skip some useless part int i; //loop invariant fscanf(input_file, "%d", &n_block); fscanf(input_file, "%d", &n_node); input *i_arr = malloc(sizeof(input) * n_node);//input data array for(i = 0; i < n_block; i++){//input data for leaf nodes fscanf(input_file, "%d %d %d %d %c %lf %lf", &(i_arr[i].thisnode), &(i_arr[i].parnode), &(i_arr[i].lcnode), &(i_arr[i].rcnode), &(i_arr[i].cutline), &(i_arr[i].width), &(i_arr[i].height)); i_arr[i].left = NULL; i_arr[i].right = NULL; i_arr[i].xcoord = 0; i_arr[i].ycoord = 0; } for(i = n_block; i < n_node; i++){//input data for non-leaf nodes fscanf(input_file, "%d %d %d %d %c", &(i_arr[i].thisnode), &(i_arr[i].parnode), &(i_arr[i].lcnode), &(i_arr[i].rcnode), &(i_arr[i].cutline)); temp_char = fgetc(input_file); while(temp_char != '\n'){ temp_char = fgetc(input_file); } i_arr[i].width = 0; i_arr[i].height = 0; i_arr[i].left = NULL; i_arr[i].right = NULL; i_arr[i].xcoord = 0; i_arr[i].ycoord = 0; } fclose(input_file); input* tree_root = Tree_construct(i_arr, n_node, n_block); //print out the screen output clock_t time_temp = clock();//the Elapsed time Pack_compute(tree_root); free_Stack1(); Cal_coords(tree_root); clock_t Elapsed_time = clock() - time_temp; printf("\nWidth: %le\n", i_arr[n_node - 1].width); printf("Height: %le\n", i_arr[n_node - 1].height); printf("\nX-coordinate: %le\n", i_arr[n_block - 1].xcoord); printf("Y-coordinate: %le\n", i_arr[n_block - 1].ycoord); printf("\nElapsed time: %le\n\n", ((double)Elapsed_time) / CLOCKS_PER_SEC); //free all the used stack memory for Stack1, Stack2 free_Stack1(); free_Stack2(); //print out the output FILE* output_file = fopen(argv[2],"w+"); if(output_file == NULL){return EXIT_FAILURE;} fprintf(output_file, "%d\n", n_block); for(i = 0; i < n_block; i++){ fprintf(output_file, "%d %le %le %le %le\n", i_arr[i].thisnode, i_arr[i].width, i_arr[i].height, i_arr[i].xcoord, i_arr[i].ycoord); } fclose(output_file); //free the memory used by the input array free(i_arr); return EXIT_SUCCESS;//if reaches here, safe return }