Add xoshiro256** generator
This commit is contained in:
		
							
								
								
									
										93
									
								
								xorshift.c
									
									
									
									
									
								
							
							
						
						
									
										93
									
								
								xorshift.c
									
									
									
									
									
								
							| @@ -11,8 +11,21 @@ typedef struct { | |||||||
|   u64 w; |   u64 w; | ||||||
| } XORShift256; | } XORShift256; | ||||||
|  |  | ||||||
| void test_xorshift_256(Pixel *data, u64 w, u64 h); | typedef struct { | ||||||
| u64 xorshift_256_generate(XORShift256 *state); |   u64 x; | ||||||
|  |   u64 y; | ||||||
|  |   u64 z; | ||||||
|  |   u64 w; | ||||||
|  | } XOShiRo256SS; | ||||||
|  |  | ||||||
|  | typedef u64(RandGenFunc)(void *s); | ||||||
|  |  | ||||||
|  | void test_xorshift_256(Image *img); | ||||||
|  | u64 xorshift_256_generate(void *s); | ||||||
|  | void test_xoshiro_256ss(Image *img); | ||||||
|  | u64 xoshiro_256ss_generate(void *s); | ||||||
|  | u64 rol64(u64 x, u64 bits); | ||||||
|  | void write_image_data(Image *img, RandGenFunc *gen_rand, void *s); | ||||||
|  |  | ||||||
| int main(int argc, char *argv[]) { | int main(int argc, char *argv[]) { | ||||||
|   struct timespec ts = {0}; |   struct timespec ts = {0}; | ||||||
| @@ -25,14 +38,22 @@ int main(int argc, char *argv[]) { | |||||||
|   u64 length = w * h; |   u64 length = w * h; | ||||||
|   Pixel data[length]; |   Pixel data[length]; | ||||||
|  |  | ||||||
| 	test_xorshift_256(data, w, h); |   Image img = { | ||||||
|  |       .width = w, | ||||||
|  |       .height = h, | ||||||
|  |       .data = data, | ||||||
|  |   }; | ||||||
|  |  | ||||||
|   write_p6_ppm("./outputs/xorshift_256.ppm", w, h, data); |   test_xorshift_256(&img); | ||||||
|  |   write_p6_ppm("./outputs/xorshift256.ppm", &img); | ||||||
|  |  | ||||||
|  |   test_xoshiro_256ss(&img); | ||||||
|  |   write_p6_ppm("./outputs/xoshiro256ss.ppm", &img); | ||||||
|  |  | ||||||
|   return EXIT_SUCCESS; |   return EXIT_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
| void test_xorshift_256(Pixel *data, u64 w, u64 h) { | void test_xorshift_256(Image *img) { | ||||||
|   XORShift256 state = { |   XORShift256 state = { | ||||||
|       .x = lrand48(), |       .x = lrand48(), | ||||||
|       .y = lrand48(), |       .y = lrand48(), | ||||||
| @@ -40,21 +61,12 @@ void test_xorshift_256(Pixel *data, u64 w, u64 h) { | |||||||
|       .w = lrand48(), |       .w = lrand48(), | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   for (u64 y = 0; y < h; ++y) { |   write_image_data(img, xorshift_256_generate, (void *)&state); | ||||||
|     for (u64 x = 0; x < w; ++x) { |  | ||||||
|       u64 i = y * w + x; |  | ||||||
|  |  | ||||||
|       u8 pixel = xorshift_256_generate(&state) % UINT8_MAX; |  | ||||||
|       data[i] = (Pixel){ |  | ||||||
|           .r = pixel, |  | ||||||
|           .g = pixel, |  | ||||||
|           .b = pixel, |  | ||||||
|       }; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| u64 xorshift_256_generate(XORShift256 *state) { | u64 xorshift_256_generate(void *s) { | ||||||
|  |   XORShift256 *state = (XORShift256 *)s; | ||||||
|  |  | ||||||
|   u64 t = state->x ^ (state->x << 11); |   u64 t = state->x ^ (state->x << 11); | ||||||
|  |  | ||||||
|   state->x = state->y; |   state->x = state->y; | ||||||
| @@ -64,3 +76,48 @@ u64 xorshift_256_generate(XORShift256 *state) { | |||||||
|  |  | ||||||
|   return state->w; |   return state->w; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void test_xoshiro_256ss(Image *img) { | ||||||
|  |   XOShiRo256SS state = { | ||||||
|  |       .x = lrand48(), | ||||||
|  |       .y = lrand48(), | ||||||
|  |       .z = lrand48(), | ||||||
|  |       .w = lrand48(), | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   write_image_data(img, xoshiro_256ss_generate, (void *)&state); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | u64 xoshiro_256ss_generate(void *s) { | ||||||
|  |   XOShiRo256SS *state = (XOShiRo256SS *)s; | ||||||
|  |  | ||||||
|  |   const u64 result = rol64(state->z * 5, 7) * 9; | ||||||
|  |   const u64 t = state->z << 17; | ||||||
|  |  | ||||||
|  |   state->y ^= state->w; | ||||||
|  |   state->x ^= state->z; | ||||||
|  |   state->z ^= state->y; | ||||||
|  |   state->w ^= state->x; | ||||||
|  |  | ||||||
|  |   state->y ^= t; | ||||||
|  |   state->x = rol64(state->x, 45); | ||||||
|  |  | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | u64 rol64(u64 x, u64 bits) { return (x << bits) | (x >> (64 - bits)); } | ||||||
|  |  | ||||||
|  | void write_image_data(Image *img, RandGenFunc *gen_rand, void *s) { | ||||||
|  |   for (u64 y = 0; y < img->height; ++y) { | ||||||
|  |     for (u64 x = 0; x < img->width; ++x) { | ||||||
|  |       u64 i = y * img->width + x; | ||||||
|  |  | ||||||
|  |       u8 pixel = gen_rand(s) % UINT8_MAX; | ||||||
|  |       img->data[i] = (Pixel){ | ||||||
|  |           .r = pixel, | ||||||
|  |           .g = pixel, | ||||||
|  |           .b = pixel, | ||||||
|  |       }; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user