מבוא לחישוב- הצעת פתרון לתרגיל בית 5 - 2010

Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 20

main.

c
#include #include #include #include <stdio.h> <string.h> <math.h> "func.h"

//consts const int MAX_LENGTH = 201; int main(void) { //input: no input. //output: performs an unique task according to the user input. returns 1. char the_str_to_encode[MAX_LENGTH]; char encoding_str[5]; int main_option, integreations_in_array = 0, integration_code; integration integrationResults[8]; main_option = askForOption(); while (1) { //break on case 3 switch (main_option) { case 1: askForStrToEncode(the_str_to_encode); askForEncodingMethod(encoding_str); encodeString(the_str_to_encode, encoding_str); printf("\nthe result is: %s\n\n", the_str_to_encode); break; case 2: integration_code = askForIntegreationCode(); while (integration_code != 4) { if (integreations_in_array < 8) integreations_in_array++; integration_code = askForIntegreationCode();
pushIntegration(integrationResults, calculateIntegralTask(integration_code));

} printInegrationsArray(integrationResults, &integreations_in_array); break; case 3: printf("Good bye!"); return (1); break;

} main_option = askForOption(); } }

func.h
#ifndef HI #define HI // structs typedef struct { char name[12]; char function[14]; double stop_condition, lower_bound, upper_bound, result; } integration; // general functions int askForOption(); int isInteger(float d); int isValueInRange(int val, int min, int max); int power(int x, int y); // strings functions void addStarAfterCapital(char str[]); void askForEncodingMethod(char str[]); void askForStrToEncode(char str[]); int countWords(const char str[]); int askForWordPosition(int words); void encodeOperation(char encodingChar, char str[]); void encodeString(char str[], const char encodingString[]); int isCapitalLetter(char chr); int isValidEncodingChr(char ch); int isValidEncodingStr(const char str[]); int isValidInputChr(char ch); int isValidInputStr(const char str[]); int inverseWord(char str[], int start); void inverseWordsInSentence(char str[]); int isVowel(char ch); void noSpaces(char str[]); void noVowels(char str[]); void validationError(); void swapInts(int *num1, int*num2); void swapChars(char *ch1, char *ch2); char lowerChar(char ch); int wordEnd(const char str[], int start); // integration functions double askForBound(int isLower, int rangeAndlessThenOne); double askForEpsilon(); int askForFunction(); int askForIntegreationCode(); int askForN(int isEven); double calculareArcSin(double x); double calculareArcSinForLessEqualsHalf(double x); double calculateCosine(double x); double calculateFirstFunction(double x); double calculateIntegral(integration new_integration, int integral_code, double func(double), double *stop_condition); integration calculateIntegralTask(int integration_code); double calculateIntegralByRomberg(double func(double), double lower_bound, double upper_bound, double epsilon); double calculateIntegralBySimpson(double func(double), int n, double lower_bound, double upper_bound); double calculateIntegralByTrapez(double func(double), int n, double lower_bound, double upper_bound); double calculateIntegralByTrapezAndPreviousN(double func(double), int previous_n, double lower_bound, double upper_bound, double previous_sum); double calculateNumInRombergTable(double num1, double num2, int j); double calculateThirdFunction(double x); void printInegrationsArray(integration integrationResults[], int *max_index); void pushIntegration(integration integrationResults[], integration integrationResult); void putFunctionString(char strToAssaign[], int funcCode); void putIntegrationTypeString(char strToAssaign[], int integrationCode); #endif

func.c
#include #include #include #include <stdio.h> <string.h> <math.h> "func.h"

//consts const int PI = 3.141592; //**********************************************// // general functions // //**********************************************// int askForOption() { //input: no input //output: the function performs the task of asking for a main option float code; printf("Hello,\nPlease choose an option:\n1. Strings\n2. Integration\n3. Exit\n"); scanf("%f", &code); while (!isInteger(code) || !isValueInRange((int) code, 1, 3)) { validationError(); scanf("%f", &code); } getchar(); return code; } int isValueInRange(int val, int min, int max) { //input: three integers named val, min and max //output: returns 1 if min<=val<=max and 0 otherwise return val >= min && val <= max; } int isInteger(float f) { //input: a float //output: returns 1 if the float is an integer return ((int) f == f); } int power(int x, int y) { //input: two integers x and y //output: x^y int z = 1; while (y > 0) { while (y % 2 == 0) { x = x * x; y = y / 2; } z = z * x; y = y - 1; } return z; } //**********************************************// // string functions // //**********************************************// int isValidInputChr(char ch) { //input: a char //output: returns 1 if the char is valid for being included in the encoded string ('a'-z', 'A'-'Z', ' ') int temp = (int) ch; return isValueInRange(temp, 97, 122) || isValueInRange(temp, 65, 90) || temp == 32; } int isValidEncodingChr(char ch) {

//input: a char //output: returns 1 if the char is valid for being included in the encoding string ('a'-d') int temp = (int) ch; return isValueInRange(temp, 97, 100) || isValueInRange(temp, 65, 68);

int isValidInputStr(const char str[]) { //input: a string //output: returns 1 if the string is a valid for being encoded (look at isValidInputChr for more info) int i = 0, len = strlen(str); for (i = 0; i < len; i++) { if (!isValidInputChr(str[i])) return 0; } return 1; } int isValidEncodingStr(const const char str[]) { //input: a string //output: returns 1 if the string is a valid for being considered as a encoding string ('a'='d' chars with no repitition) int i, len = strlen(str); for (i = 0; i < len; i++) if (!isValidEncodingChr(str[i])) return 0; //repetition validations if (len > 1) if (str[0] == str[1])return 0; if (len > 2) if (str[0] == str[2] || str[1] == str[2]) return 0; if (len > 3) if (str[0] == str[3] || str[1] == str[3] || str[2] == str[3]) return 0; return 1; } int countWords(const char str[]) { //input: a string //output: number of words in string int i, flag = 1, len = strlen(str), counter = 0; for (i = 0; i < len; i++) { if (str[i] != ' ' && flag == 1) { counter++; flag = 0; } else if (str[i] == ' ') { flag = 1; } } return counter; } int wordEnd(const char str[], int start) { //input: a string and a start integer (should represent a position in the string) //output: returns the position in which the word that shart at position "start" ends int i, len = strlen(str); for (i = start; i < len; i++) { if (str[i] == ' ') return i - 1; } return i - 1; } void swapInts(int *num1, int*num2) { //input: two integer pointers //output: the functions swaps between the values of the cells int temp; temp = *num1; *num1 = *num2; *num2 = temp; }

void swapChars(char *ch1, char *ch2) { //input: two chars pointers

//output: the functions swaps between the values of the cells int temp; temp = *ch1; *ch1 = *ch2; *ch2 = temp; } int inverseWord(char str[], int start) { //input: a string and a start integer (should represent a position in the string) //output: inverses the word which start at position "start" and returns the poisition in which the word ends int end2, end = wordEnd(str, start), temp; end2 = end; while (end > start) { swapChars(&str[start], &str[end]); start++; end--; } return end2; } char lowerChar(char ch) { //input a-z letter //output: returns the char capital letter int temp = (int) ch; if (temp <= 90) { temp += 32; } return (char) temp; } void encodeOperation(char encodingChar, char str[]) { //input an encoding char by which the string "str" sould be encoded //output: performs encoding to "str" according to the encoding-char switch (lowerChar(encodingChar)) { case 'a': noVowels(str); break; case 'b': inverseWordsInSentence(str); break; case 'c': noSpaces(str); break; case 'd': addStarAfterCapital(str); break; } } void encodeString(char str[], const char encodingString[]) { //input: two strings //output: encodes str by the encoding-string int i, len = strlen(encodingString); for (i = 0; i < len; i++) { encodeOperation(encodingString[i], str); } } int isCapitalLetter(char chr) { //input: a char //output: returns 1 if char is a capital letter return isValueInRange((int) chr, 65, 90); }

void addStarAfterCapital(char str[]) { //input: a string //output: changes the string so that after a capital letter there would be a '*'

int i, j, len = strlen(str); for (i = 0; i < len; i++) { if (isCapitalLetter(str[i])) { for (j = len + 2; j > i; j--) { str[j] = str[j - 1]; } str[i + 1] = '*'; i++; len++; } } } void noSpaces(char str[]) { //input: a string //output: changes the string so that no more then one space between words int i, j, counter = 0, len = strlen(str); for (i = len - 1; i >= 0; i--) { if (str[i] == ' ') { counter++; } else if (counter > 0) { counter--; for (j = i + 1; j <= len - counter + 1; j++) { str[j] = str[j + counter]; } len = strlen(str); counter = 0; } } if (counter > 0) { for (j = 0; j <= len - counter + 1; j++) { str[j] = str[j + counter]; } } } int isVowel(char ch) { //input: a char //output: 1 if thr char is one of the following: 'a', 'e', 'i', 'o', 'u' ch = lowerChar(ch); return (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u'); } void inverseWordsInSentence(char str[]) { //input: a string //output: inverses all the words in sentence except the one that is got as an input from user int words = countWords(str), len = strlen(str), flag = 1, counter = 0; int i, notToInverse = words > 0 ? askForWordPosition(words) : 0; for (i = 0; i < len; i++) { if (str[i] != ' ' && flag) { counter++; if (counter != notToInverse) i = inverseWord(str, i); flag = 0; } else if (str[i] == ' ') { flag = 1; } } if (!counter) printf("(blank sentence, hence no need to ask for a word index)\n"); } void noVowels(char str[]) { //input: a string "str" //output: cutting the lettes 'a', 'e', 'i', 'o', 'u' from "str" int i, j, len = strlen(str); for (i = len; i >= 0; i--) { if (isVowel(str[i])) { for (j = i; j < len; j++) str[j] = str[j + 1]; len--; } }

} void validationError() { //input: no input //output: prints the sentence "Wrong input. Please try again:" printf("Wrong input. Please try again:\n"); } int askForWordPosition(int words) { //input: number of words of a sentence //output: the functions performs the task of asking the user for the ordinal number of an word with validations and returns this value float num; printf("Please enter word number:\n"); scanf("%f", &num); while (!isInteger(num) || words < num) { validationError(); scanf("%f", &num); } return num; } void getStr(char str[]) { int i = 0; do { str[i] = getchar(); i++; } while (str[i - 1] != '\n'); str[i - 1] = '\0'; } void askForStrToEncode(char str[]) { //input: a string "str" //output: the functions performs the task of asking the user for a string to encode, performs validations and puting this string in str printf("Please enter a sentence:\n"); getStr(str); while (!isValidInputStr(str)) { validationError(); getStr(str); } } void askForEncodingMethod(char encoding_str[]) { //input: a string "str" //output: the functions performs the task of asking for en encoding-string and puting it in "str" int i, length_flag = 2; //first value of length_flag prevents error message in first iteration char tempChar; printf("Please choose a method:\n"); while (!isValidEncodingStr(encoding_str) || length_flag != 1 || i == 0) { if (length_flag != 2) validationError(); length_flag = 1; i = 0; tempChar = getchar(); while (i < 4 && tempChar != '\n') { encoding_str[i] = tempChar; tempChar = getchar(); i++; } encoding_str[i ] = '\0'; if (i == 4 && tempChar != '\n') { length_flag = 0; while (getchar() != '\n'); } } } //**********************************************// // integration functions // //**********************************************//

int askForIntegreationCode() { //input: no input //output: the function performs the task of asking for an integration type and retunrns the chosen option float code; printf("Please choose integration method:\n1. Trapez\n2. Simpson\n3. Romberg\n4. Back to main menu\n"); scanf("%f", &code); while (!isInteger(code) || !isValueInRange((int) code, 1, 4)) { validationError(); scanf("%f", &code); } return code; } int askForFunction() { //input: no input //output: the function performs the task of asking for a function and returns the chosen function number float code; printf("Please choose a function:\n1. 1-e^(-0.1x)\n2. arcsin(x)\n3. 6+x^4\n4. cos(x)\n"); scanf("%f", &code); while (!isInteger(code) || !isValueInRange((int) code, 1, 4)) { validationError(); scanf("%f", &code); } return code; } int askForN(int isEven) { //input: isEven flag //output: the function performs the task of asking for a N for trapez/simpson method. If isEven equals 1 validation is performed that n is even float n; int intN; printf("Please enter n:\n"); scanf("%f", &n); intN = (int) n; while (!isInteger(n) || !isValueInRange(intN, 1, 20) || !(!isEven || (isEven && (intN % 2) == 0))) { validationError(); scanf("%f", &n); intN = (int) n; } return intN; } double askForEpsilon() { //input: no input //output: the function performs the task of asking for an epsilon for Romberg method. double epsilon; printf("Please enter an epsilon:\n"); scanf("%lf", &epsilon); while (epsilon <= 0) { validationError(); scanf("%lf", &epsilon); } return epsilon; } double askForBound(int isLower, int rangeAndlessThenOne) { //input: isLower flag and rangeAndlessThenOne flag //output: the function performs the task of asking for a bound for function integral and returns it. isLower determines what to ask and rangeAndlessThenOne determines wheter to check that // the range absoulute is less then one double n; printf("Please enter %s bound:\n", isLower ? "lower" : "upper"); scanf("%lf", &n); if (rangeAndlessThenOne) { while (fabs(n) > 1) { validationError(); scanf("%lf", &n); }

} return n;

double calculateFirstFunction(double x) { //input: a double x //output: returns f(x) where f(x)=1 - exp(-0.1 * x) return 1 - exp(-0.1 * x); } double calculareArcSin(double x) { //input: double x //output: returns arcsin(x) approximation double xAbs = fabs(x); if (xAbs <= 0.5) { return calculareArcSinForLessEqualsHalf(x); } else { double z = sqrt(0.5 * (1 - xAbs)); int xSign = x > 0 ? 1 : -1; return xSign * (PI / 2 - 2 * calculareArcSinForLessEqualsHalf(z)); } } double calculareArcSinForLessEqualsHalf(double x) { //input: double x between -0.5<=x<=0.5 //output: returns arcsin(x) approximation double xSqr = x*x; return x * (1 + xSqr * (0.16666782 + xSqr * (0.07494697 + xSqr * (0.04552063 + xSqr * (0.02399402 + xSqr * 0.04241734))))); } double calculateThirdFunction(double x) { //input: a float x //output: returns f(x) where f(x)=6+x^4 double xSqr = x*x, xPowerFour = xSqr*xSqr; return 6 + xPowerFour; } double calculateCosine(double x) { //input: a double x //output: returns cos(x) double xSqr = x*x, xPowerFour = xSqr*xSqr, nominator, denominator; nominator = 0.9999999992448 - 0.4558922220771 * xSqr + 0.205121130021 * xPowerFour; denominator = 1 + 0.0441077396346 * xSqr + 0.0008996261464 * xPowerFour; return (nominator / denominator); } double calculateIntegralByTrapez(double func(double), int n, double lower_bound, double upper_bound) { //input: a function whose input and returned value are doubles, integer n, and two double bounds //output: calculate and returns the inegral of func between the given bounds with presision of n divsions by the trapez method double range = upper_bound - lower_bound; double h = range / n; int i; double currentX, tempSum = 0; for (i = 1; i < n; i++) { currentX = lower_bound + h*i; tempSum += func(currentX); } return h * 0.5 * (2 * tempSum + func(lower_bound) + func(upper_bound)); }

double calculateIntegralByTrapezAndPreviousN(double func(double), int previous_n, double lower_bound, double upper_bound, double previous_sum) { //input: a function whose input and returned value are doubles, integer previous_n, two double bounds, and the integral sum of this integral with precision of previous_n*2

//output: calculate and returns the inegral of func between the given bounds with presision of n divsions by the trapez method relying on the calculation of this integral with previous_n*2 double range = upper_bound - lower_bound; double previous_h = range / previous_n; double current_h = 0.5 * previous_h; int i; double currentX, tempSum = 0; //lower_bound += current_h; for (i = 0; i < previous_n; i++) { //currentX = lower_bound + previous_h * i; currentX = lower_bound + current_h * (2 * i + 1); tempSum += func(currentX); } return 0.5 * previous_sum + current_h * (tempSum); } double calculateIntegralBySimpson(double func(double), int n, double lower_bound, double upper_bound) { //input: a function whose input and returned value are doubles, integer n, and two double bounds //output: calculate and returns the inegral of func between the given bounds with presision of n divsions by the simpson method double range = upper_bound - lower_bound; int half_n = 0.5 * n; double h = range / n; int i; double currentX, tempSum1 = 0, tempSum2 = 0; for (i = 1; i < half_n; i++) { currentX = lower_bound + 2 * h*i; tempSum1 += func(currentX); tempSum2 += func(currentX + h); } }
return h / 3 * (2 * tempSum1 + 4 * (tempSum2 + func(lower_bound + h)) + func(lower_bound) + func(upper_bound));

double calculateIntegralByRomberg(double func(double), double lower_bound, double upper_bound, double epsilon) { // input: a function whose input and returned value are doubles, n (max squares division), and two double bounds // output: calculate and returns the inegral of func between the given bounds with presision of epsilon divsions by the romberg method static double nums[41][41]; int again_flag = 1; int row_num = 0; int i, col_num, num_of_squares = 1; double current_val, prev_val, temp_epsilon; nums[0][0] = calculateIntegralByTrapez(func, 1, lower_bound, upper_bound); current_val = nums[0][0]; while (again_flag || row_num == 40) { prev_val = current_val; col_num = 0; row_num++;
nums[row_num][0] = calculateIntegralByTrapezAndPreviousN(func, num_of_squares, lower_bound, upper_bound, nums[row_num - 1][0]);

num_of_squares *= 2; for (i = 1; i <= row_num; i++) {

nums[row_num - i][i] = calculateNumInRombergTable(nums[row_num - i + 1][i - 1], nums[row_num - i][i - 1], row_num);

//printf("***%f****%f*\n",nums[row_num - i + 1][i-1],nums[row_num - i][i-1]); //debug } current_val = nums[0][row_num]; //printf("curent: %lf prev: %lf\n", current_val, prev_val); //debug temp_epsilon = fabs(current_val - prev_val) / prev_val; //printf("epsilon now: %lf\n", temp_epsilon); //debug again_flag = temp_epsilon >epsilon; } //debugging the table /*for (i = 0; i <= row_num; i++) { int j; for (j = 0; j < row_num - i; j++) { printf("%0.3f ", nums[j][i]); } printf("\n"); }*/ return nums[0][row_num];

double calculateNumInRombergTable(double num1, double num2, int j) { //input: two succesive numbers in Roberg table (the same column) //output: the number at the next column int fourPower = power(4, j); return ((fourPower * num1 - num2) / (fourPower - 1)); } double ezer(double x) { //input: double x //output: 1/x.used to check romberg return 1 / x; } double calculateIntegral(integration new_integration, int integral_code, double func(double), double *stop_condition) { //input: integration record, integral_code, a function whose input is a double and which returns double and a pointer to the stop condition of the integration //output: calculates the integral according to the input and returns it. Also updates stop_condition int n; double epsilon, result; switch (integral_code) { case 1: //trapez n = askForN(0); *stop_condition = (double) n; break; case 2://simpson n = askForN(1); *stop_condition = (double) n; break; case 3://romberg epsilon = askForEpsilon(); *stop_condition = epsilon; break; } return result; } void putFunctionString(char strToAssaign[], int funcCode) { //input: a string and a function code //output: assaigns the string of the function whose code is funcCode to strToAssaign switch (funcCode) { case 1: strcpy(strToAssaign, "1-e^(-0.1x) "); break; case 2: strcpy(strToAssaign, "arcsin(x) "); break; case 3: strcpy(strToAssaign, "6+x^4 "); break; case 4: strcpy(strToAssaign, "cos(x) "); break; } strToAssaign[13] = '\0'; }
result = calculateIntegralByTrapez(func, n, new_integration.lower_bound, new_integration.upper_bound);

result = calculateIntegralBySimpson(func, n, new_integration.lower_bound, new_integration.upper_bound);

result = calculateIntegralByRomberg(func, new_integration.lower_bound, new_integration.upper_bound, epsilon);

void putIntegrationTypeString(char strToAssaign[], int integrationCode) { //input: a string and an integration code //output: assaigns the string of the integration whose code is integrationCode to strToAssaign switch (integrationCode) { case 1: strcpy(strToAssaign, "Trapez ");

break; case 2: case 3: strcpy(strToAssaign, "Simpson break; strcpy(strToAssaign, "Romberg break; } strToAssaign[11] = '\0'; } integration calculateIntegralTask(int integration_code) { //input: integration code (1 for trapez, 2 for simpson and 3 for romberg) //output: performs the task of calculating ingeral according to the user input integration new_integration; putIntegrationTypeString(new_integration.name, integration_code); int function_option = askForFunction(); putFunctionString(new_integration.function, function_option); int rangeAbslessEqualsOne = function_option == 2 || function_option == 4; new_integration.lower_bound = askForBound(1, rangeAbslessEqualsOne); new_integration.upper_bound = askForBound(0, rangeAbslessEqualsOne); while (new_integration.upper_bound < new_integration.lower_bound) { validationError(); new_integration.lower_bound = askForBound(1, rangeAbslessEqualsOne); new_integration.upper_bound = askForBound(0, rangeAbslessEqualsOne); } switch (function_option) { case 1: break; case 2: break; case 3: break; case 4:
new_integration.result = calculateIntegral(new_integration, integration_code, calculateFirstFunction, &new_integration.stop_condition);

"); ");

new_integration.result = calculateIntegral(new_integration, integration_code, calculareArcSin, &new_integration.stop_condition);

new_integration.result = calculateIntegral(new_integration, integration_code, calculateThirdFunction, &new_integration.stop_condition);

break; } printf("The result is: %0.6f\n", new_integration.result); return new_integration;

new_integration.result = calculateIntegral(new_integration, integration_code, calculateCosine, &new_integration.stop_condition);

void pushIntegration(integration integrationResults[], integration integrationResult) { //input: the integration array and the last integration //output: push the last integration into the integrations array (one integration goes out) int i; for (i = 7; i > 0; i--) { integrationResults[i] = integrationResults[i - 1]; } integrationResults[0] = integrationResult; }

void printInegrationsArray(integration integrationResults[], int *max_index) { //input: the integration array and the last integration index //output: prints integration table int i; if (*max_index == 0) { printf("No data\n"); return; }

printf("Method function accuracy lower bound Upper bound Result\n"); for (i = 0; i < *max_index; i++) { integration x = integrationResults[i]; printf("%s%s%-13.5f%-16.2f%-16.2f%f\n", x.name, x.function, x.stop_condition, x.lower_bound, x.upper_bound, x.result); } *max_index = 0; }

Makefile
a.out: func.o main.o gcc func.o main.o functions.o: func.c gcc -c func.c main.o: main.c gcc -c main.c

) : (

You might also like