1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 | #include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "polydivide.h"
// Prints a double array terminated by INFINITY
void print_array(double const *a) {
putchar('{');
for (; !isinf(*a); ++a) { printf(" %.2f", *a); }
printf(" }");
}
// Compares using Total Squared Error; passes if error < tolerance
bool test(double const *a, double const *b, double const *expected_q,
double const *expected_r, double const tolerance) {
printf("\nTEST: a = ");
print_array(a);
printf(", b = ");
print_array(b);
putchar('\n');
double *r;
double *q = entry(a, b, &r);
bool success = true;
double error = 0;
for (double const *qi = q, *eqi = expected_q; !isinf(*eqi); ++qi, ++eqi) {
double const residual = *qi - *eqi;
error += residual * residual;
}
if (error < tolerance) {
printf("Q SUCCESS (error: %f): Q = ", error);
print_array(q);
putchar('\n');
} else {
printf("Q FAILED (error: %f): \n EXPECTED: ", error);
print_array(expected_q);
printf("\n GOT: ");
print_array(q);
putchar('\n');
success = false;
}
error = 0;
for (double const *ri = r, *eri = expected_r; !isinf(*eri); ++ri, ++eri) {
error += (*ri - *eri) * (*ri - *eri);
}
if (error < tolerance) {
printf("R SUCCESS (error: %f): R = ", error);
print_array(r);
putchar('\n');
} else {
printf("R FAILED (error: %f): \n EXPECTED: ", error);
print_array(expected_r);
printf("\n GOT: ");
print_array(r);
putchar('\n');
success = false;
}
free(r);
free(q);
return success;
}
struct test_case {
double const *a;
double const *b;
double const *expected_q;
double const *expected_r;
};
int main(int argc, char const *argv[]) {
double const tolerance = .000000001;
struct test_case const test_suite[] = {
// Basic tests
{(double const[]){-42, 0, -12, 1, INFINITY},
(double const[]){-3, 1, INFINITY},
(double const[]){-27, -9, 1, INFINITY},
(double const[]){-123, INFINITY}},
{(double const[]){-21, -5, 4, INFINITY},
(double const[]){-3, 1, INFINITY}, (double const[]){7, 4, INFINITY},
(double const[]){0, INFINITY}},
{(double const[]){12, 30, 40, INFINITY},
(double const[]){1, 3, 4, INFINITY}, (double const[]){10, INFINITY},
(double const[]){2, 0, INFINITY}},
// Testing a case where the remainder isn't degree 0
{(double const[]){-13, 2, -9, 0, 4, 2, INFINITY},
(double const[]){1, -2, 1, INFINITY},
(double const[]){11, 14, 8, 2, INFINITY},
(double const[]){-24, 10, INFINITY}},
// Testing a case that actually gives fractions
{(double const[]){0, 0, 0, 1, INFINITY},
(double const[]){1, -2, 3, INFINITY},
(double const[]){2.0 / 9.0, 1.0 / 3.0, INFINITY},
(double const[]){-2.0 / 9.0, 1.0 / 9.0, INFINITY}},
// Testing a numerator with a lower degree than the denominator
{(double const[]){1, 2, INFINITY},
(double const[]){-3, 1, 2, 1, INFINITY}, (double const[]){INFINITY},
(double const[]){1, INFINITY}},
// Testing empty numerator
{(double const[]){INFINITY}, (double const[]){-3, 1, INFINITY},
(double const[]){INFINITY}, (double const[]){INFINITY}}};
int const num_tests = sizeof test_suite / sizeof *test_suite;
int num_success = 0;
for (int test_index = 0; test_index < num_tests; ++test_index) {
struct test_case const test_case = test_suite[test_index];
num_success += test(test_case.a, test_case.b, test_case.expected_q,
test_case.expected_r, tolerance);
}
printf("\n%d of %d tests passed\n", num_success, num_tests);
return 0;
}
|
Lyric has done this exact same thing before but without comments in cg #16 i think
I'm sorry for this. I wanted to do something in APL but learning APL in one week while working didn't work out.
well you bamboozled me so good on you
post a comment