mylab1functions.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911
  1. //Stephen Stengel
  2. //hpc lab1 header file
  3. #ifndef STEPHEN_STENGEL_LAB1
  4. #define STEPHEN_STENGEL_LAB1
  5. #include <stdio.h>
  6. #include <stdlib.h> //exit(), malloc()
  7. #include <string.h> //strcmp()
  8. #include <time.h> //time()
  9. #include <limits.h> //INT_MAX
  10. #include <math.h> //math functions
  11. #include <ctype.h> //isspace(), isdigit(), etc.
  12. //~ #include <stdbool.h> //bool type
  13. #include <unistd.h> //access() check file exists.
  14. #define TRUE 1
  15. #define FALSE 0
  16. //These are a bit higher than what runs in a reasonable time. 100/10 is about an hour.
  17. #define GLOBAL_MAX_M 125
  18. #define GLOBAL_MAX_N 12
  19. #define RAND_MULT 1000
  20. #define MAX_COMMAND_LEN 2000
  21. #define HELP_TEXT_PATH "helpfile"
  22. struct node
  23. {
  24. double value;
  25. int row;
  26. int col;
  27. struct node *right;
  28. struct node *down;
  29. };
  30. //Helper functions
  31. int checkForHelpCommands(int argc, char** argv);
  32. _Bool strIsHelp(char* aString);
  33. void printTextFile(char* inputPath);
  34. int* generateArray(int mySize, int* outArray);
  35. int printIntArray(int* array, int length);
  36. double getElapsedTime(struct timespec start, struct timespec finish);
  37. _Bool isInputTwoNumbers(int argc, char **argv);
  38. int checkInput(int argc, char **argv);
  39. double doubleRand(double low, double high);
  40. double** createSquareArray(int size);
  41. double** fillSquareArrayRandomDoubles(double** myArray, int size);
  42. int freeSquareDoubleArray(double** myArray, int size);
  43. double** copySquareDoubleArray(double** myArray, int size);
  44. _Bool isStringAllDigits(char* myString);
  45. void printSquareDoubleArray(double **myArray, int size);
  46. double** createIdentityMatrix(int size);
  47. int testFunctions();
  48. void printListValues(struct node* head);
  49. int getListSize(struct node* head);
  50. struct node* copyNode(struct node* myNode);
  51. void freeList(struct node* head);
  52. //stuff
  53. int runArrayTests(int maxM, int maxN);
  54. int powerArrays(double **myArray, int sizeM, int N);
  55. double **multSquareArrays(double **original, double **intermediate, double **output, int size);
  56. int printArrayDataPoint(int M, int N, int i, int j, double time);
  57. int deleteFileIfExists(char * myFilename);
  58. int runListTests(int maxM, int maxN);
  59. struct node* createList(int size);
  60. struct node* nodeAlloc();
  61. void printNodeValues(struct node* myNode);
  62. struct node* constructNode();
  63. struct node* multTwoSquareLists(struct node* A, struct node* B);
  64. double** fillArrayWithListVals(struct node* head);
  65. struct node* advanceNode(struct node* myNode, int row, int col);
  66. struct node* zeroAList(struct node* myList);
  67. int listDemo(int M, int N);
  68. struct node* powerLists(struct node* myList, int sizeThisRound, int ennThisRound);
  69. struct node* copyList(struct node* myList);
  70. int printListDataPoint(int maxM, int maxN, int size, int ennThisRound, double lowest);
  71. _Bool isInputThreeNumbers(int argc, char **argv);
  72. int testFunctions()
  73. {
  74. int testSize = 3;
  75. double **myArray = createSquareArray(testSize);
  76. myArray = fillSquareArrayRandomDoubles(myArray, testSize);
  77. printSquareDoubleArray(myArray, testSize);
  78. double** identity = createIdentityMatrix(testSize);
  79. printSquareDoubleArray(identity, testSize);
  80. printf("first times identity...\n");
  81. double **output = createSquareArray(testSize);
  82. output = multSquareArrays(identity, myArray, output, testSize);
  83. printSquareDoubleArray(output, testSize);
  84. freeSquareDoubleArray(myArray, testSize);
  85. freeSquareDoubleArray(identity, testSize);
  86. freeSquareDoubleArray(output, testSize);
  87. return 0;
  88. }
  89. //Creates identity matrix of given size. Malloc inide. free outside.
  90. double** createIdentityMatrix(int size)
  91. {
  92. double** myArray = (double**)malloc( sizeof(double*) * size );
  93. for (int i = 0; i < size; i++)
  94. {
  95. //calloc( #elements, size in bytes), sets all to zero.
  96. myArray[i] = (double*)calloc( size, sizeof(double) );
  97. myArray[i][i] = 1;
  98. }
  99. return myArray;
  100. }
  101. //listMalloc inside, freeList outside
  102. struct node* createIdentityList(int size)
  103. {
  104. struct node* myList = createList(size);
  105. struct node* i = myList;
  106. while (i != NULL)
  107. {
  108. struct node* j = i;
  109. while (j != NULL)
  110. {
  111. if (j->row == j->col)
  112. {
  113. j->value = 1;
  114. }
  115. else
  116. {
  117. j->value = 0;
  118. }
  119. j = j->right;
  120. }
  121. i = i->down;
  122. }
  123. return myList;
  124. }
  125. struct node* zeroAList(struct node* myList)
  126. {
  127. struct node* i = myList;
  128. while (i != NULL)
  129. {
  130. struct node* j = i;
  131. while (j != NULL)
  132. {
  133. j->value = 0;
  134. j = j->right;
  135. }
  136. i = i->down;
  137. }
  138. return myList;
  139. }
  140. int listDemo(int M, int N)
  141. {
  142. //
  143. int size = M;
  144. struct node* head = createList(size);
  145. freeList(head);
  146. struct node* A = createList(size);
  147. struct node* B = createList(size);
  148. //~ struct node* B = createIdentityList(size); //to see if it works!
  149. struct node* output = multTwoSquareLists(A, B);
  150. freeList(A);
  151. freeList(B);
  152. freeList(output);
  153. return 0;
  154. }
  155. int runListTests(int maxM, int maxN)
  156. {
  157. //~ listDemo(maxM, maxN);
  158. struct timespec start, finish;
  159. double lowest = INT_MAX;
  160. double elapsedTime = -1;
  161. for (int i = 0; i < maxM; i++)
  162. {
  163. for (int j = 0; j < maxN; j++)
  164. {
  165. //~ int sizeThisRound = i;
  166. int ennThisRound = j;
  167. //do three tests timing each
  168. lowest = INT_MAX;
  169. for (int k = 0; k < 3; k++)
  170. {
  171. clock_gettime(CLOCK_MONOTONIC, &start);
  172. int size = i;
  173. struct node* A = createList(size);
  174. struct node* B = createList(size);
  175. for (int hey = 0; hey < ennThisRound - 1; hey++)
  176. {
  177. struct node* output = multTwoSquareLists(A, B);
  178. freeList(output);
  179. }
  180. elapsedTime = getElapsedTime(start, finish);
  181. freeList(A);
  182. freeList(B);
  183. //~ powerLists(myList, sizeThisRound, ennThisRound); //
  184. if (elapsedTime < lowest)
  185. {
  186. lowest = elapsedTime;
  187. }
  188. printListDataPoint(maxM, maxN, size, ennThisRound, lowest);
  189. }
  190. }
  191. }
  192. return 0;
  193. }
  194. int printListDataPoint(int M, int N, int i, int j, double time)
  195. {
  196. char dataFolder[] = "../data/";
  197. char dataBackupName[1000];
  198. sprintf(dataBackupName, "%slab1-CLISTSdata-M%d-N%d.txt", dataFolder, M, N);
  199. FILE *myFile = fopen(dataBackupName, "a");
  200. fprintf(myFile, "%d %d %f\n", i, j, time);
  201. fclose(myFile);
  202. return 0;
  203. }
  204. //creates intermediate with maloc( returns intermediate) free list outside.
  205. struct node* powerLists(struct node* myList, int size, int N)
  206. {
  207. printf("POWER LIST!\n");
  208. //~ struct node* original = copyList(myList);
  209. struct node* intermediate = copyList(myList);
  210. //~ intermediate = zeroAList(intermediate);
  211. for (int i = 1; i < N; i++)
  212. {
  213. struct node* output = createList(size);
  214. //~ output = multTwoSquareLists(original, intermediate);
  215. output = multTwoSquareLists(myList, myList);
  216. //copy output into intermediate
  217. intermediate = copyList(output);
  218. freeList(output);
  219. }
  220. printListValues(intermediate);
  221. //~ freeSquareDoubleArray(intermediate, sizeM);
  222. //~ freeSquareDoubleArray(originalCopy, sizeM);
  223. return myList;
  224. }
  225. struct node* copyList(struct node* myList)
  226. {
  227. //create an array to hold the nodes' addresses for linking.
  228. int size = getListSize(myList);
  229. struct node* reference[size][size];
  230. struct node* inode = myList;
  231. int i = 0;
  232. while (inode != NULL)
  233. {
  234. struct node* jnode = inode;
  235. int j = 0;
  236. while (jnode != NULL)
  237. {
  238. reference[i][j] = constructNode();
  239. reference[i][j]->row = i;
  240. reference[i][j]->col = j;
  241. reference[i][j]->value = jnode->value;
  242. jnode = jnode->right;
  243. }
  244. inode = inode->down;
  245. }
  246. //link nodes.
  247. for (i = 0; i < size; i++)
  248. {
  249. for (int j = 0; j < size; j++)
  250. {
  251. //there might be a more clever way to do this.
  252. if (i != size - 1)
  253. {
  254. reference[i][j]->down = reference[i+1][j];
  255. }
  256. if (j != size - 1)
  257. {
  258. reference[i][j]->right = reference[i][j+1];
  259. }
  260. }
  261. }
  262. struct node* head = reference[0][0];
  263. //~ printListValues(head);
  264. return head;
  265. }
  266. //Multiplies two SQUARE lists. Returns pointer to its head. Uses malloc.
  267. //free with freeList.
  268. struct node* multTwoSquareLists(struct node* A, struct node* B)
  269. {
  270. int size = getListSize(A);
  271. struct node* output = createList(size);
  272. output = zeroAList(output);
  273. //~ printf("print output after creation:\n");
  274. //~ printListValues(output);
  275. //~ double** aVectors = createSquareArray(size);
  276. //~ double** bVectors = createSquareArray(size);
  277. //fill vectors with values from lists in case I need them.
  278. //~ aVectors = fillArrayWithListVals(A);
  279. //~ bVectors = fillArrayWithListVals(B);
  280. struct node* tA = A;
  281. struct node* tB = B;
  282. struct node* tO = output;
  283. //~ int iCount = 0;
  284. //if current row/col wrong, advance.
  285. for (int i = 0; i < size; i++)
  286. {
  287. //reset heads each loop.
  288. tA = A;
  289. tB = B;
  290. tO = output;
  291. for (int j = 0; j < size; j++)
  292. {
  293. tA = A;
  294. tB = B;
  295. tO = output;
  296. tO = advanceNode(tO, i, j);
  297. for (int k = 0; k < size; k++)
  298. {
  299. //~ tA = A;
  300. //~ tB = B;
  301. tA = advanceNode(tA, i, k);
  302. tB = advanceNode(tB, k, j);
  303. tO->value += (tA->value * tB->value);
  304. }
  305. }
  306. }
  307. //~ printSquareDoubleArray(aVectors, size);
  308. //~ printSquareDoubleArray(bVectors, size);
  309. //~ printf("printing list output: \n");
  310. //~ printListValues(output);
  311. //~ //fill b vectors
  312. //~ //free stuff
  313. //~ freeSquareDoubleArray(aVectors, size);
  314. //~ freeSquareDoubleArray(bVectors, size);
  315. return output;
  316. }
  317. struct node* advanceNode(struct node* myNode, int row, int col)
  318. {
  319. while (myNode->row < row)
  320. {
  321. myNode = myNode->down;
  322. }
  323. while (myNode->col < col)
  324. {
  325. myNode = myNode->right;
  326. }
  327. return myNode;
  328. }
  329. void printListValues(struct node* head)
  330. {
  331. struct node* i = head;
  332. while (i != NULL)
  333. {
  334. struct node* j = i;
  335. while (j != NULL)
  336. {
  337. printf("%f", j->value);
  338. j = j->right;
  339. if (j)
  340. {
  341. printf("\t");
  342. }
  343. }
  344. printf("\n");
  345. i = i->down;
  346. }
  347. printf("\n");
  348. }
  349. //uses malloc.
  350. double** fillArrayWithListVals(struct node* head)
  351. {
  352. int size = getListSize(head);
  353. double** myArray = createSquareArray(size);
  354. struct node* i = head;
  355. int iCount = 0;
  356. while (i != NULL)
  357. {
  358. int jCount = 0;
  359. struct node* j = i;
  360. while (j != NULL)
  361. {
  362. myArray[iCount][jCount] = j->value;
  363. j = j->right;
  364. jCount++;
  365. }
  366. i = i->down;
  367. iCount++;
  368. }
  369. return myArray;
  370. }
  371. //creates the list, returns pointer to head. malloc used. must free.
  372. struct node* createList(int size)
  373. {
  374. //create an array to hold the nodes' addresses for linking.
  375. struct node* reference[size][size];
  376. //create nodes and fill with values.
  377. for (int i = 0; i < size; i++)
  378. {
  379. for (int j = 0; j < size; j++)
  380. {
  381. reference[i][j] = constructNode();
  382. reference[i][j]->row = i;
  383. reference[i][j]->col = j;
  384. //~ printNodeValues(reference[i][j]);
  385. }
  386. }
  387. //link nodes.
  388. for (int i = 0; i < size; i++)
  389. {
  390. for (int j = 0; j < size; j++)
  391. {
  392. //there might be a more clever way to do this.
  393. if (i != size - 1)
  394. {
  395. reference[i][j]->down = reference[i+1][j];
  396. }
  397. if (j != size - 1)
  398. {
  399. reference[i][j]->right = reference[i][j+1];
  400. }
  401. }
  402. }
  403. struct node* head = reference[0][0];
  404. //~ printListValues(head);
  405. return head;
  406. }
  407. void freeList(struct node* head)
  408. {
  409. struct node* currentRow = head;
  410. //~ int count = 0;
  411. while (currentRow != NULL)
  412. {
  413. struct node* currentCol = currentRow;
  414. while ( currentCol != NULL )
  415. {
  416. struct node* tmp = currentCol;
  417. currentCol = currentCol->right;
  418. //~ printf("value of thing being freed: %f\n", tmp->value);
  419. free(tmp);
  420. //~ count++;
  421. }
  422. currentRow = currentRow->down;
  423. }
  424. //~ printf("number of frees: %d\n", count);
  425. }
  426. //returns the size of the list as if it were a square array. size x size
  427. int getListSize(struct node* myNode)
  428. {
  429. struct node* tmp = myNode;
  430. int count = 0;
  431. while (tmp != NULL)
  432. {
  433. count++;
  434. tmp = tmp->right;
  435. }
  436. return count;
  437. }
  438. //creates and returns an elementwise copy of a node. uses malloc.
  439. struct node* copyNode(struct node* myNode)
  440. {
  441. struct node* copy = nodeAlloc();
  442. copy->col = myNode->col;
  443. copy->row = myNode->row;
  444. copy->right = myNode->right;
  445. copy->down = myNode->down;
  446. copy->value = myNode->value;
  447. return copy;
  448. }
  449. //Creates a node. Malloc inside.
  450. struct node* constructNode()
  451. {
  452. struct node* myNode = nodeAlloc();
  453. myNode->value = doubleRand(-1, 1) * RAND_MULT;
  454. myNode->row = -1;
  455. myNode->col = -1;
  456. myNode->right = NULL;
  457. myNode->down = NULL;
  458. return myNode;
  459. }
  460. void printNodeValues(struct node* N)
  461. {
  462. printf("\nNode %d,%d...\n", N->row, N->col);
  463. printf("This address: %p\n", N);
  464. printf("value: %f\n", N->value);
  465. printf("addr right: %p\taddr down: %p\n", N->right, N->down);
  466. }
  467. //mallocs space for a node. free outside.
  468. struct node* nodeAlloc()
  469. {
  470. return (struct node*)malloc( sizeof(struct node) );
  471. }
  472. int deleteFileIfExists(char * myFilename)
  473. {
  474. if ( access(myFilename, F_OK) == 0 )
  475. {
  476. //exists
  477. char command[MAX_COMMAND_LEN];
  478. sprintf(command, "rm %s", myFilename);
  479. printf("deleting file: %s\n", myFilename);
  480. system( command );
  481. }
  482. else
  483. {
  484. printf("could not find file: %s\n", myFilename);
  485. }
  486. return 0;
  487. }
  488. int runArrayTests(int maxM, int maxN)
  489. {
  490. //create timer variables.
  491. struct timespec start, finish;
  492. double lowest = INT_MAX;
  493. double elapsedTime = -1;
  494. for (int i = 1; i < maxM + 1; i++)
  495. {
  496. for (int j = 1; j < maxN + 1; j++)
  497. {
  498. //create array
  499. int sizeThisRound = i;
  500. int ennThisRound = j;
  501. double **myArray = createSquareArray(sizeThisRound);
  502. myArray = fillSquareArrayRandomDoubles(myArray, sizeThisRound);
  503. //do three tests timing each
  504. lowest = INT_MAX;
  505. for (int k = 0; k < 3; k++)
  506. {
  507. clock_gettime(CLOCK_MONOTONIC, &start);
  508. powerArrays(myArray, sizeThisRound, ennThisRound);
  509. elapsedTime = getElapsedTime(start, finish);
  510. if (elapsedTime < lowest)
  511. {
  512. lowest = elapsedTime;
  513. }
  514. }
  515. //append the i, j, time to a file
  516. printArrayDataPoint(maxM, maxN, sizeThisRound, ennThisRound, lowest);
  517. freeSquareDoubleArray(myArray, sizeThisRound);
  518. }
  519. }
  520. return 0;
  521. }
  522. int freeSquareDoubleArray(double** myArray, int size)
  523. {
  524. for (int i = 0; i < size; i++)
  525. {
  526. free(myArray[i]);
  527. }
  528. free(myArray);
  529. return 0;
  530. }
  531. //Creates square array. Returns pointer to it. Must free outside.
  532. double** createSquareArray(int size)
  533. {
  534. double **myArray = (double**)malloc( sizeof(double*) * size );
  535. for (int i = 0; i < size; i++)
  536. {
  537. myArray[i] = (double*)malloc( sizeof(double) * size );
  538. }
  539. return myArray;
  540. }
  541. //fills a square array with random double values.
  542. //returns pointer to array, lol
  543. double** fillSquareArrayRandomDoubles(double** myArray, int size)
  544. {
  545. for (int i = 0; i < size; i++)
  546. {
  547. for (int j = 0; j < size; j++)
  548. {
  549. myArray[i][j] = doubleRand(-1, 1) * RAND_MULT;
  550. }
  551. }
  552. return myArray;
  553. }
  554. //need to delete file at start of experiment if it exists.
  555. int printArrayDataPoint(int M, int N, int i, int j, double time)
  556. {
  557. //~ dataFolder = "../data/"
  558. //~ dataBackupName = f"lab1-data-M{maxSquareSize}-N{maxN}.txt"
  559. //~ dataBackupNamePath = dataFolder + dataBackupName
  560. char dataFolder[] = "../data/";
  561. char dataBackupName[1000];
  562. sprintf(dataBackupName, "%slab1-CARRAYdata-M%d-N%d.txt", dataFolder, M, N);
  563. FILE *myFile = fopen(dataBackupName, "a");
  564. fprintf(myFile, "%d %d %f\n", i, j, time);
  565. fclose(myFile);
  566. return 0;
  567. }
  568. int powerArrays(double **myArray, int sizeM, int N)
  569. {
  570. double **originalCopy = copySquareDoubleArray(myArray, sizeM);
  571. double **intermediate = copySquareDoubleArray(myArray, sizeM);
  572. for (int i = 1; i < N; i++)
  573. {
  574. double **output = createSquareArray(sizeM);
  575. output = multSquareArrays(originalCopy, intermediate, output, sizeM);
  576. //copy output into intermediate
  577. intermediate = copySquareDoubleArray(output, sizeM);
  578. freeSquareDoubleArray(output, sizeM);
  579. }
  580. freeSquareDoubleArray(intermediate, sizeM);
  581. freeSquareDoubleArray(originalCopy, sizeM);
  582. return 0;
  583. }
  584. //Creates a copy of a square double array. Must be freed outside.
  585. double** copySquareDoubleArray(double** myArray, int size)
  586. {
  587. double **myCopy = (double**)malloc( sizeof(double*) * size );
  588. for (int i = 0; i < size; i++)
  589. {
  590. myCopy[i] = (double*)malloc( sizeof(double) * size );
  591. for (int j = 0; j < size; j++)
  592. {
  593. myCopy[i][j] = myArray[i][j];
  594. }
  595. }
  596. return myCopy;
  597. }
  598. double **multSquareArrays(double **original, double **intermediate, double **output, int size)
  599. {
  600. for (int i = 0; i < size; i++)
  601. {
  602. for (int j = 0; j < size; j++)
  603. {
  604. for (int k = 0; k < size; k++)
  605. {
  606. //outArray[i,j] += A[i,k] * B[k,j]
  607. output[i][j] += original[i][k] * intermediate[k][j];
  608. }
  609. }
  610. }
  611. return output;
  612. }
  613. //Simple random double function that I found. rand/max gives a fraction
  614. //which is multiplied by the range.
  615. double doubleRand(double low, double high)
  616. {
  617. return ( (double)rand() * ( high - low ) ) / (double)RAND_MAX + low;
  618. }
  619. int checkInput(int argc, char **argv)
  620. {
  621. //~ if ( !isInputTwoNumbers(argc, argv) )
  622. if ( !isInputThreeNumbers(argc, argv) )
  623. {
  624. printf("Input must be three positive integers!\n");
  625. printTextFile(HELP_TEXT_PATH);
  626. exit( -1);
  627. }
  628. //I can add more checks for isDigit and such here.
  629. return 0;
  630. }
  631. _Bool isInputTwoNumbers(int argc, char **argv)
  632. {
  633. if (argc != 3)
  634. {
  635. return FALSE;
  636. }
  637. else
  638. {
  639. for (int i = 1; i < argc; i++) //Start at 1 to skip name.
  640. {
  641. //if any character not digit return false.
  642. if ( !isStringAllDigits(argv[i]) )
  643. {
  644. return FALSE;
  645. }
  646. }
  647. }
  648. return TRUE;
  649. }
  650. _Bool isInputThreeNumbers(int argc, char **argv)
  651. {
  652. if (argc != 4)
  653. {
  654. return FALSE;
  655. }
  656. else
  657. {
  658. for (int i = 1; i < argc; i++) //Start at 1 to skip name.
  659. {
  660. //if any character not digit return false.
  661. if ( !isStringAllDigits(argv[i]) )
  662. {
  663. return FALSE;
  664. }
  665. }
  666. }
  667. return TRUE;
  668. }
  669. //Returns TRUE if all characters are digits.
  670. _Bool isStringAllDigits(char* myString)
  671. {
  672. int c = 0;
  673. while (myString[c] != 0)
  674. {
  675. if ( !isdigit(myString[c]) )
  676. {
  677. return FALSE;
  678. }
  679. c++;
  680. }
  681. return TRUE;
  682. }
  683. //Timer function. Returns elapsed time.
  684. double getElapsedTime(struct timespec start, struct timespec finish)
  685. {
  686. double timeElapsed = 0;
  687. clock_gettime(CLOCK_MONOTONIC, &finish);//end
  688. timeElapsed = (finish.tv_sec - start.tv_sec);
  689. timeElapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0; //convert to nanoseconds
  690. return timeElapsed;
  691. }
  692. //Check if user needs help.
  693. int checkForHelpCommands(int argc, char** argv)
  694. {
  695. if ( ((argc > 1) && strIsHelp(argv[1])) || (argc == 1) )
  696. {
  697. printTextFile(HELP_TEXT_PATH);
  698. exit(0);
  699. }
  700. return 0;
  701. }
  702. //Returns true if input string is a help command.
  703. _Bool strIsHelp(char* aString)
  704. {
  705. if ( (strcmp(aString, "help") == 0)
  706. || (strcmp(aString, "-help") == 0)
  707. || (strcmp(aString, "--help") == 0)
  708. || (strcmp(aString, "h") == 0)
  709. || (strcmp(aString, "-h") == 0)
  710. || (strcmp(aString, "--h") == 0)
  711. )
  712. {
  713. return TRUE;
  714. }
  715. return FALSE;
  716. }
  717. //print a text file. Input string of the filename-path
  718. void printTextFile(char* inputPath)
  719. {
  720. FILE* myFile = fopen(inputPath, "r");
  721. int c; //int because EOF is usually negative.
  722. if ( myFile )
  723. {
  724. while ( (c = getc(myFile)) != EOF )
  725. {
  726. putchar(c);
  727. }
  728. fclose(myFile);
  729. }
  730. }
  731. void printSquareDoubleArray(double **myArray, int size)
  732. {
  733. for (int i = 0; i < size; i++)
  734. {
  735. for (int j = 0; j < size; j++)
  736. {
  737. printf("%f", myArray[i][j]);
  738. if ( j != size - 1 )
  739. {
  740. printf("\t");
  741. }
  742. }
  743. printf("\n");
  744. }
  745. printf("\n");
  746. }
  747. #endif