Skip to content

Commit

Permalink
add data/array.c, migrate fns from math/vec.c, update chull & matrix …
Browse files Browse the repository at this point in the history
…tests
  • Loading branch information
postspectacular committed Jul 21, 2016
1 parent b88c554 commit ad814cd
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 78 deletions.
190 changes: 190 additions & 0 deletions src/data/array.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#include <string.h>

#include "data/array.h"
#include "math/math.h"

float *ct_array_add2_f32(const float *a,
const float *b,
float *out,
size_t num,
size_t fstridea,
size_t fstrideb,
size_t fstrideo) {
float *ptr = out, *aa = (float *)a, *bb = (float *)b;
while (num--) {
*ptr = *aa + *bb;
aa += fstridea;
bb += fstrideb;
ptr += fstrideo;
}
return out;
}

float *ct_array_mul2_f32(const float *a,
const float *b,
float *out,
size_t num,
size_t fstridea,
size_t fstrideb,
size_t fstrideo) {
float *ptr = out, *aa = (float *)a, *bb = (float *)b;
while (num--) {
*ptr = *aa * *bb;
aa += fstridea;
bb += fstrideb;
ptr += fstrideo;
}
return out;
}

float ct_array_reduce_sum_f32(const float *p, size_t num, size_t fstride) {
float sum = 0;
float *ptr = (float *)p;
while (num--) {
sum += *ptr;
ptr += fstride;
}
return sum;
}

intptr_t ct_array_reduce_sum_i32(const int32_t *p, size_t num, size_t istride) {
intptr_t sum = 0;
int32_t *ptr = (int32_t *)p;
while (num--) {
sum += *ptr;
ptr += istride;
}
return sum;
}

uintptr_t ct_array_reduce_sum_u32(const uint32_t *p,
size_t num,
size_t istride) {
uintptr_t sum = 0;
uint32_t *ptr = (uint32_t *)p;
while (num--) {
sum += *ptr;
ptr += istride;
}
return sum;
}

float *ct_array_reverse_f32_imm(float *ptr, size_t num, size_t fstride) {
CT_CHECK(fstride <= 32, "fstride > 32");
uint8_t tmp[128];
switch (fstride) {
case 1: {
for (size_t i = 0, n2 = num >> 1, end = (num - 1); i < n2; i++, end--) {
float tmp = ptr[i];
ptr[i] = ptr[end];
ptr[end] = tmp;
}
} break;
case 2: {
for (size_t i = 0, n2 = ((num >> 1) << 1), end = (num - 1) << 1; i < n2;
i += 2, end -= 2) {
float tmp = ptr[i];
float tmp2 = ptr[i + 1];
ptr[i] = ptr[end];
ptr[i + 1] = ptr[end + 1];
ptr[end] = tmp;
ptr[end + 1] = tmp2;
}
} break;
default: {
size_t stride = fstride * sizeof(float);
for (size_t i = 0, n2 = num / 2 * fstride, end = (num - 1) * fstride;
i < n2; i += fstride, end -= fstride) {
memcpy(tmp, &ptr[i], stride);
memcpy(&ptr[i], &ptr[end], stride);
memcpy(&ptr[end], tmp, stride);
}
}
}
return ptr;
fail:
return NULL;
}

void *ct_array_reverse_imm(void *ptr, size_t num, size_t stride) {
CT_CHECK(stride <= 128, "stride > 128");
uint8_t tmp[128];
for (size_t i = 0, n2 = num / 2 * stride, end = (num - 1) * stride; i < n2;
i += stride, end -= stride) {
memcpy(tmp, &ptr[i], stride);
memcpy(&ptr[i], &ptr[end], stride);
memcpy(&ptr[end], tmp, stride);
}
return ptr;
fail:
return NULL;
}

void *ct_array_reverse(const void *src, size_t num, size_t stride, void *dest) {
CT_CHECK(stride <= 128, "stride > 128");
for (size_t i = 0, len = num * stride, end = len - stride; i < len;
i += stride, end -= stride) {
memcpy(&dest[end], &src[i], stride);
}
return dest;
fail:
return NULL;
}

int ct_array_deltaeq_f32(const float *a,
const float *b,
float eps,
size_t num) {
for (size_t i = 0; i < num; i++) {
if (!ct_deltaeqf(a[i], b[i], eps)) {
return 0;
}
}
return 0;
}

int ct_array_compare_f32(const float *a,
const float *b,
float eps,
size_t num) {
for (size_t i = 0; i < num; i++) {
float delta = a[i] - b[i];
if (delta < -eps) {
return -1;
} else if (delta > eps) {
return 1;
}
}
return 0;
}

int ct_array_tostring_f32(char *buf,
int bufsz,
const float *p,
size_t num,
size_t fstride) {
if (snprintf(buf, bufsz, "[") > 0) {
size_t j = 1;
bufsz -= j;
float *ptr = (float *)p;
for (size_t i = 0; i < num && bufsz > 0; i++) {
int res = snprintf(&buf[j], bufsz, "%1.4f", *ptr);
if (res < 0) {
return -1;
}
if (i < num - 1) {
buf[j + res] = ' ';
res++;
}
bufsz -= res;
j += res;
ptr += fstride;
}
if (bufsz > 1) {
buf[j] = ']';
buf[j + 1] = 0;
return j + 1;
}
}
return -1;
}
36 changes: 36 additions & 0 deletions src/data/array.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include <stdint.h>

#include "cthing.h"

float *ct_array_add2_f32(const float *a,
const float *b,
float *out,
size_t num,
size_t fstridea,
size_t fstrideb,
size_t fstrideo);
float *ct_array_mul2_f32(const float *a,
const float *b,
float *out,
size_t num,
size_t fstridea,
size_t fstrideb,
size_t fstrideo);

float ct_array_reduce_sum_f32(const float *p, size_t num, size_t fstride);
intptr_t ct_array_reduce_sum_i32(const int32_t *p, size_t num, size_t istride);
uintptr_t ct_array_reduce_sum_u32(const uint32_t *p,
size_t num,
size_t istride);

float *ct_array_reverse_f32_imm(float *ptr, size_t num, size_t fstride);
void *ct_array_reverse_imm(void *ptr, size_t num, size_t stride);
void *ct_array_reverse(const void *src, size_t num, size_t stride, void *out);

int ct_array_deltaeq_f32(const float *a, const float *b, float eps, size_t num);
int ct_array_compare_f32(const float *a, const float *b, float eps, size_t num);
int ct_array_tostring_f32(char *buf,
int bufsz,
const float *p,
size_t num,
size_t fstride);
66 changes: 4 additions & 62 deletions src/math/vec.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <float.h>
#include <stdio.h>

#include "data/array.h"
#include "math/vec.h"

ct_export CT_Vec2f *ct_vec2f(float x, float y, CT_MPool *mpool) {
Expand Down Expand Up @@ -156,67 +157,6 @@ ct_export int ct_bounds3fp(float *ptr,
return 1;
}

int ct_deltaeqfp(const float *a, const float *b, float eps, size_t num) {
for (size_t i = 0; i < num; i++) {
if (!ct_deltaeqf(a[i], b[i], eps)) {
return 0;
}
}
return 0;
}

int ct_comparefp(const float *a, const float *b, float eps, size_t num) {
for (size_t i = 0; i < num; i++) {
float delta = a[i] - b[i];
if (delta < -eps) {
return -1;
} else if (delta > eps) {
return 1;
}
}
return 0;
}

int ct_tostringfp(char *buf, int bufsz, const float *p, size_t num) {
if (snprintf(buf, bufsz, "[") > 0) {
size_t j = 1;
bufsz -= j;
for (size_t i = 0; i < num && bufsz > 0; i++) {
int res = snprintf(&buf[j], bufsz, "%1.4f", p[i]);
if (res < 0) {
return -1;
}
if (i < num - 1) {
buf[j + res] = ' ';
res++;
}
bufsz -= res;
j += res;
}
if (bufsz > 1) {
buf[j] = ']';
buf[j + 1] = 0;
return j + 1;
}
}
return -1;
}

void *ct_reverse_array_imm(void *ptr, size_t num, size_t stride) {
CT_CHECK(stride <= 128, "stride > 128");
uint8_t tmp[128];
for (size_t i = 0, n2 = num / 2 * stride, end = (num - 1) * stride; i < n2;
i += stride) {
memcpy(tmp, &ptr[i], stride);
memcpy(&ptr[i], &ptr[end], stride);
memcpy(&ptr[end], tmp, stride);
end -= stride;
}
return ptr;
fail:
return NULL;
}

static size_t hull2f(CT_Vec2f *points, size_t num, CT_Vec2f *hull) {
size_t len = 0;
for (size_t i = 0; i < num; i++) {
Expand All @@ -237,6 +177,8 @@ size_t ct_convexhull2f(CT_Vec2f *points, size_t num, CT_Vec2f *hull) {
}
qsort(points, num, sizeof(CT_Vec2f), ct_compare2fv_xy);
size_t len = hull2f(points, num, hull);
len += hull2f(ct_reverse_array_imm(points, num, sizeof(CT_Vec2f)), num, hull + len);
ct_array_reverse_f32_imm((float *)points, num, 2);
//ct_array_reverse_imm(points, num, sizeof(CT_Vec2f));
len += hull2f(points, num, hull + len);
return len - (ct_compare2fv_xy(&hull[0], &hull[1]) == 0);
}
4 changes: 0 additions & 4 deletions src/math/vec_arrayops.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@

CT_BEGIN_DECLS

int ct_deltaeqfp(const float* a, const float* b, float eps, size_t num);
int ct_comparefp(const float* a, const float* b, float eps, size_t num);
int ct_tostringfp(char* buf, int bufsz, const float* p, size_t num);

void ct_translate2f(float* ptr, CT_Vec2f* t, size_t num, size_t fstride);
void ct_scale2f(float* ptr, CT_Vec2f* t, size_t num, size_t fstride);
void ct_translate3f(float* ptr, CT_Vec3f* t, size_t num, size_t fstride);
Expand Down
19 changes: 10 additions & 9 deletions test/matrix.c
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
#include "test/test.h"

#include "data/array.h"
#include "math/matrix.h"
#include "math/vec.h"

CT_TEST_DECLS

static char buf[256];

#define ASSERT_VEC(a, n, ...) \
{ \
int res = ct_comparefp((float*)a, FVEC(__VA_ARGS__), EPS, n); \
__testAsserts++; \
if (res) { \
ct_tostringfp(buf, 256, (float*)a, n); \
CT_ERROR("%s", buf); \
return 1; \
} \
#define ASSERT_VEC(a, n, ...) \
{ \
int res = ct_array_compare_f32((float*)a, FVEC(__VA_ARGS__), EPS, n); \
__testAsserts++; \
if (res) { \
ct_array_tostring_f32(buf, 256, (float*)a, n, 1); \
CT_ERROR("%s", buf); \
return 1; \
} \
}

#define ASSERT_VEC4F(v, ...) ASSERT_VEC(v, 4, __VA_ARGS__)
Expand Down
20 changes: 17 additions & 3 deletions test/vec.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,26 @@ int test_vec_hash() {

int test_convex_hull() {
CT_Vec2f points[] = {{0, 0}, {5, 0}, {2, 0.1}, {0, 5}, {1, 2}};
CT_Vec2f hull[6];
CT_Vec2f hull[32];
size_t len = ct_convexhull2f(points, 5, hull);
CT_IS(3 == len, "hull len: %zu", len);
for (size_t i = 0; i < len; i++) {
CT_INFO("hull %zu: %f,%f", i, hull[i].x, hull[i].y);
//for (size_t i = 0; i < len; i++) {
// CT_INFO("hull %zu: %f,%f", i, hull[i].x, hull[i].y);
//}
CT_Vec2f *samples = malloc(1e5 * sizeof(CT_Vec2f));
for (size_t i = 0; i < 1e5; i++) {
ct_set2fxy(&samples[i], ct_rand_norm(), ct_rand_norm());
}
ct_set2fxy(&samples[100], 1, -1);
ct_set2fxy(&samples[500], 1, 1);
ct_set2fxy(&samples[1000], -1, 1);
ct_set2fxy(&samples[5000], -1, -1);
len = ct_convexhull2f(samples, 1e5, hull);
CT_IS(4 == len, "hull len: %zu", len);
//for (size_t i = 0; i < len; i++) {
// CT_INFO("hull %zu: %f,%f", i, hull[i].x, hull[i].y);
//}
free(samples);
return 0;
}

Expand Down

0 comments on commit ad814cd

Please sign in to comment.