Add xoshiro256** generator
This commit is contained in:
		
							
								
								
									
										93
									
								
								xorshift.c
									
									
									
									
									
								
							
							
						
						
									
										93
									
								
								xorshift.c
									
									
									
									
									
								
							| @@ -11,8 +11,21 @@ typedef struct { | ||||
|   u64 w; | ||||
| } XORShift256; | ||||
|  | ||||
| void test_xorshift_256(Pixel *data, u64 w, u64 h); | ||||
| u64 xorshift_256_generate(XORShift256 *state); | ||||
| typedef struct { | ||||
|   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[]) { | ||||
|   struct timespec ts = {0}; | ||||
| @@ -25,14 +38,22 @@ int main(int argc, char *argv[]) { | ||||
|   u64 length = w * h; | ||||
|   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; | ||||
| } | ||||
|  | ||||
| void test_xorshift_256(Pixel *data, u64 w, u64 h) { | ||||
| void test_xorshift_256(Image *img) { | ||||
|   XORShift256 state = { | ||||
|       .x = lrand48(), | ||||
|       .y = lrand48(), | ||||
| @@ -40,21 +61,12 @@ void test_xorshift_256(Pixel *data, u64 w, u64 h) { | ||||
|       .w = lrand48(), | ||||
|   }; | ||||
|  | ||||
|   for (u64 y = 0; y < h; ++y) { | ||||
|     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, | ||||
|       }; | ||||
|     } | ||||
|   } | ||||
|   write_image_data(img, xorshift_256_generate, (void *)&state); | ||||
| } | ||||
|  | ||||
| u64 xorshift_256_generate(XORShift256 *state) { | ||||
| u64 xorshift_256_generate(void *s) { | ||||
|   XORShift256 *state = (XORShift256 *)s; | ||||
|  | ||||
|   u64 t = state->x ^ (state->x << 11); | ||||
|  | ||||
|   state->x = state->y; | ||||
| @@ -64,3 +76,48 @@ u64 xorshift_256_generate(XORShift256 *state) { | ||||
|  | ||||
|   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