Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <pthread.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <math.h>
- #include <ctype.h>
- #include <complex.h>
- int lines, n_threads, degree, *block_limit;
- char **attractor;
- char **convergence;
- char *color[10];
- char *it_color[99];
- double _Complex *root;
- int max_it = 98;
- int *done;
- //methods called in newton
- static inline double _Complex compute_power(double _Complex z0, int power){
- double _Complex tmp = z0;
- for(int i=1; i<power; i++){
- z0 *=tmp;
- }
- return z0;
- }
- static inline double _Complex newton_step(double _Complex x_loc){
- switch(degree){
- case 1:
- x_loc = 1;
- break;
- case 2:
- x_loc = (x_loc+1/x_loc)/2;
- break;
- default:
- x_loc = x_loc - x_loc/degree + 1/(degree *compute_power(x_loc,degree-1));
- }
- return x_loc;
- }
- void* write(){
- char str1[26], str2[27];
- sprintf(str1, "newton_attractors_x%i.ppm", degree);
- sprintf(str2, "newton_convergence_x%i.ppm", degree);
- FILE * fp1 = fopen (str1,"w");
- FILE * fp2 = fopen (str2,"w");
- char form[] = "P3 \n";
- char *dim = (char*)malloc(lines*2+2);
- sprintf(dim,"%d %d \n", lines, lines);
- char *numcol = (char*)malloc(4);
- sprintf(numcol,"%d \n", 9);
- fwrite(form, 1, strlen(form), fp1);
- fwrite(dim, 1, strlen(dim), fp1);
- fwrite(numcol, 1, strlen(numcol), fp1);
- char *maxcolor = (char*)malloc(5);
- sprintf(maxcolor,"%d \n", max_it);
- fwrite(form, 1, strlen(form), fp2);
- fwrite(dim, 1, strlen(dim), fp2);
- fwrite(maxcolor, 1, strlen(maxcolor), fp2);
- struct timespec tim, tim2;
- tim.tv_sec = 0;
- tim.tv_nsec = 100;
- for(int ix=0; ix<lines*lines; ix++){
- while(done[ix]==0){
- nanosleep(&tim,&tim2);
- }
- fwrite(attractor[ix], sizeof(attractor[ix])-2 ,1, fp1);
- fwrite(convergence[ix],sizeof(convergence[ix])+1,1, fp2);
- }
- free(dim);
- free(numcol);
- free(maxcolor);
- fclose(fp1);
- fclose(fp2);
- return NULL;
- }
- void* newton(void *restrict arg) {
- int x = ((int*)arg)[0];
- free(arg);
- int ix, dv;
- if(degree == 1){
- for (int i=0; i<lines; i++){
- for(int j=0; j<lines; j++){
- attractor[i*lines+j]="2 2 2 ";
- convergence[i*lines+j]= "01 01 01 ";
- done[i*lines+j]=1;
- }}
- }
- else{
- int low_block_limit=block_limit[x]; int up_block_limit=block_limit[x+1];
- double _Complex x_loc, x_tmp;
- double tolerance = 0.000001;
- double max = 10000000000;
- int max_it_loc = max_it;
- double increment = 4.0/(lines-1);
- for (int i=low_block_limit; i<up_block_limit; i++){
- for(int j=0; j<lines; j++){
- x_loc = -2 + j*increment + 2*I - i*increment*I;
- for (ix=1, dv= 0; ; ix++){
- x_loc=newton_step(x_loc);
- if (creal(x_loc)*creal(x_loc)+cimag(x_loc)*cimag(x_loc) <tolerance || creal(x_loc) > max || creal(x_loc) < -max ||cimag(x_loc) > max || cimag(x_loc) < -max){
- attractor[i*lines+j] = color[9];
- convergence[i*lines+j] = it_color[ix];
- done[i*lines+j]=1;
- break;
- }
- if (ix > max_it_loc){
- attractor[i*lines+j] = color[9];
- convergence[i*lines+j] = it_color[max_it_loc];
- done[i*lines+j]=1;
- break;
- }
- for (int jx=0; jx<degree; jx++){
- x_tmp = x_loc-root[jx];
- if(creal(x_tmp)*creal(x_tmp)+cimag(x_tmp)*cimag(x_tmp)<tolerance){
- dv=1;
- attractor[i*lines+j] = color[jx];
- convergence[i*lines+j] = it_color[ix];
- done[i*lines+j]=1;
- break;
- }
- }
- if (dv !=0){
- break;
- }
- }
- }
- }}
- return NULL;
- }
- int main(int argc, char *argv[]){
- //assigning comands line arguments to varibles
- char tmp1[10], tmp2[10];
- if (argc != 4 || argv[1][0] != '-' || argv[2][0] !='-'){
- printf("Invalid of arguments \n");
- return 0;
- }
- else if (argv[1][1] == 'l' && argv[2][1] == 't' ) {
- memset(tmp1, 0, sizeof(tmp1));
- memcpy(tmp1, &argv[1][2], strlen(argv[1]) - 2);
- memset(tmp2, 0, sizeof(tmp2));
- memcpy(tmp2, &argv[2][2], strlen(argv[2]) - 2);
- }
- else if (argv[1][1] == 't' && argv[2][1] == 'l' ) {
- memset(tmp2, 0, sizeof(tmp2));
- memcpy(tmp2, &argv[1][2], strlen(argv[1]) - 2);
- memset(tmp1, 0, sizeof(tmp1));
- memcpy(tmp1, &argv[2][2], strlen(argv[2]) - 2);
- }
- lines = (size_t) strtol(tmp1, NULL, 10);
- n_threads = (size_t) strtol(tmp2, NULL, 10);
- degree = (size_t) strtol(argv[3], NULL, 10);
- int *block_size = (int*)malloc(sizeof(int)*(n_threads+1));
- block_limit = (int*)malloc(sizeof(int)*(n_threads+1));
- //creating blocks
- int even = lines%n_threads;
- int block = lines/n_threads;
- int ix, jx;
- for (ix =0; ix<n_threads+1; ix++){
- block_limit[ix] =block*ix;
- }
- if (even != 0){
- for (ix=1; ix<even+1; ix++){
- block_limit[ix] +=ix;
- }
- for (; ix<n_threads+1; ix++){
- block_limit[ix] += even;
- }}
- done=(int*)malloc(sizeof(int)*lines*lines);
- for(int i=0; i<lines*lines; i++){
- done[i]=0;
- }
- // defining strings for colors
- color[0]="2 5 0 ";
- color[1]="3 0 0 ";
- color[2]="2 0 3 ";
- color[3]="2 4 7 ";
- color[4]="5 7 3 ";
- color[5]="2 5 5 ";
- color[6]="3 4 5 ";
- color[7]="0 8 0 ";
- color[8]="7 6 4 ";
- color[9]="2 2 2 ";
- char tmp[99][11];
- for(int i=0; i<99; i++){
- sprintf(tmp[i], "%d%d %d%d %d%d ", i/10, i%10, i/10, i%10, i/10, i%10);
- it_color[i] =tmp[i];
- }
- //initializing matrices
- attractor = (char**)malloc(sizeof(char*)*lines*lines);
- convergence = (char**)malloc(sizeof(char*)*lines*lines);
- //defining true roots
- root = (double _Complex*)malloc(sizeof(double _Complex)*degree);
- double tmproot;
- for (int ix = 0; ix < degree; ix ++) {
- tmproot = ix * 2 * M_PI / degree;
- root[ix] = cos(tmproot) + sin(tmproot) * I;
- }
- //creating threads
- size_t tx;
- int ret;
- pthread_t threads[n_threads];
- for (tx=0; tx < n_threads; tx++) {
- double ** arg = malloc(sizeof(tx));
- arg[0] = (double*)tx;
- if ((ret = pthread_create(threads+tx, NULL, newton, (void*)arg))) {
- printf("Error creating thread: %d\n", ret);
- exit(1);
- }}
- if ((ret = pthread_create(threads+n_threads, NULL, write, NULL))) {
- printf("Error creating thread: %d\n", ret);
- exit(1);
- }
- //joining threads
- for (tx=0; tx < n_threads; ++tx) {
- if ((ret = pthread_join(threads[tx], NULL))) {
- printf("Error joining thread: %d\n", ret);
- exit(1);
- }
- }
- if ((ret = pthread_join(threads[n_threads], NULL))) {
- printf("Error joining thread: %d\n", ret);
- exit(1);
- }
- free(attractor);
- free(convergence);
- free(root);
- free(block_limit);
- free(block_size);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement