1 | // =============================================================== // |
---|
2 | // // |
---|
3 | // File : AP_matrix.cxx // |
---|
4 | // Purpose : // |
---|
5 | // // |
---|
6 | // Institute of Microbiology (Technical University Munich) // |
---|
7 | // http://www.arb-home.de/ // |
---|
8 | // // |
---|
9 | // =============================================================== // |
---|
10 | |
---|
11 | #include "AP_matrix.hxx" |
---|
12 | |
---|
13 | #include <arbdbt.h> |
---|
14 | #include <aw_window.hxx> |
---|
15 | #include <aw_root.hxx> |
---|
16 | #include <aw_awar.hxx> |
---|
17 | #include <cfloat> |
---|
18 | |
---|
19 | #define ap_assert(cond) arb_assert(cond) |
---|
20 | |
---|
21 | // ------------------ |
---|
22 | // AP_matrix |
---|
23 | |
---|
24 | AP_matrix::AP_matrix(long si) { |
---|
25 | ARB_calloc(m, si); |
---|
26 | for (long i=0; i<si; i++) { |
---|
27 | ARB_calloc(m[i], si); |
---|
28 | } |
---|
29 | size = si; |
---|
30 | } |
---|
31 | |
---|
32 | AP_matrix::~AP_matrix() { |
---|
33 | for (long i=0; i<size; i++) { |
---|
34 | free(m[i]); |
---|
35 | } |
---|
36 | free(m); |
---|
37 | } |
---|
38 | |
---|
39 | // --------------------------- |
---|
40 | // AP_userdef_matrix |
---|
41 | |
---|
42 | void AP_userdef_matrix::set_desc(char**& which_desc, int idx, const char *desc) { |
---|
43 | if (!which_desc) ARB_calloc(which_desc, get_size()); |
---|
44 | which_desc[idx] = strdup(desc); |
---|
45 | } |
---|
46 | |
---|
47 | void AP_userdef_matrix::create_awars(AW_root *awr) { |
---|
48 | char buffer[1024]; |
---|
49 | int x, y; |
---|
50 | for (x = 0; x<get_size(); x++) { |
---|
51 | if (x_description[x]) { |
---|
52 | for (y = 0; y<get_size(); y++) { |
---|
53 | if (y_description[y]) { |
---|
54 | sprintf(buffer, "%s/B%s/B%s", awar_prefix, x_description[x], y_description[y]); |
---|
55 | if (x==y) { |
---|
56 | awr->awar_float(buffer, 0)->set_minmax(0.0, 2.0); |
---|
57 | } |
---|
58 | else { |
---|
59 | awr->awar_float(buffer, 1.0)->set_minmax(0.0, 2.0); |
---|
60 | } |
---|
61 | } |
---|
62 | |
---|
63 | } |
---|
64 | } |
---|
65 | } |
---|
66 | } |
---|
67 | void AP_userdef_matrix::update_from_awars(AW_root *awr) { |
---|
68 | char buffer[1024]; |
---|
69 | int x, y; |
---|
70 | for (x = 0; x<get_size(); x++) { |
---|
71 | if (x_description[x]) { |
---|
72 | for (y = 0; y<get_size(); y++) { |
---|
73 | if (y_description[y]) { |
---|
74 | sprintf(buffer, "%s/B%s/B%s", awar_prefix, x_description[x], y_description[y]); |
---|
75 | this->set(x, y, awr->awar(buffer)->read_float()); |
---|
76 | } |
---|
77 | } |
---|
78 | } |
---|
79 | } |
---|
80 | } |
---|
81 | |
---|
82 | void AP_userdef_matrix::create_input_fields(AW_window *aww) { |
---|
83 | char buffer[1024]; |
---|
84 | int x, y; |
---|
85 | aww->create_button(NULp, " "); |
---|
86 | for (x = 0; x<get_size(); x++) { |
---|
87 | if (x_description[x]) { |
---|
88 | aww->create_button(NULp, x_description[x]); |
---|
89 | } |
---|
90 | } |
---|
91 | aww->at_newline(); |
---|
92 | for (x = 0; x<get_size(); x++) { |
---|
93 | if (x_description[x]) { |
---|
94 | aww->create_button(NULp, x_description[x]); |
---|
95 | for (y = 0; y<get_size(); y++) { |
---|
96 | if (y_description[y]) { |
---|
97 | sprintf(buffer, "%s/B%s/B%s", awar_prefix, x_description[x], y_description[y]); |
---|
98 | aww->create_input_field(buffer, 4); |
---|
99 | } |
---|
100 | } |
---|
101 | aww->at_newline(); |
---|
102 | } |
---|
103 | } |
---|
104 | } |
---|
105 | |
---|
106 | void AP_userdef_matrix::normize() { // set values so that average of non diag elems == 1.0 |
---|
107 | int x, y; |
---|
108 | double sum = 0.0; |
---|
109 | double elems = 0.0; |
---|
110 | for (x = 0; x<get_size(); x++) { |
---|
111 | if (x_description[x]) { |
---|
112 | for (y = 0; y<get_size(); y++) { |
---|
113 | if (y!=x && y_description[y]) { |
---|
114 | sum += this->get(x, y); |
---|
115 | elems += 1.0; |
---|
116 | } |
---|
117 | } |
---|
118 | } |
---|
119 | } |
---|
120 | if (sum == 0.0) return; |
---|
121 | sum /= elems; |
---|
122 | for (x = 0; x<get_size(); x++) { |
---|
123 | for (y = 0; y<get_size(); y++) { // LOOP_VECTORIZED |
---|
124 | this->set(x, y, get(x, y)/sum); |
---|
125 | } |
---|
126 | } |
---|
127 | } |
---|
128 | |
---|
129 | AP_userdef_matrix::~AP_userdef_matrix() { |
---|
130 | for (long i=0; i<get_size(); i++) { |
---|
131 | if (x_description) free(x_description[i]); |
---|
132 | if (y_description) free(y_description[i]); |
---|
133 | } |
---|
134 | free(x_description); |
---|
135 | free(y_description); |
---|
136 | free(awar_prefix); |
---|
137 | } |
---|
138 | |
---|
139 | // -------------------------------------------------------------------------------- |
---|
140 | |
---|
141 | #ifdef UNIT_TESTS |
---|
142 | #ifndef TEST_UNIT_H |
---|
143 | #include <test_unit.h> |
---|
144 | #endif |
---|
145 | |
---|
146 | void TEST_AP_smatrix() { |
---|
147 | // TEST_REJECT(true); // let it fail! |
---|
148 | |
---|
149 | const int SIZE = 10; |
---|
150 | AP_smatrix m(SIZE); |
---|
151 | |
---|
152 | TEST_EXPECT_EQUAL(m.size(), SIZE); |
---|
153 | TEST_EXPECT_EQUAL(m.fast_get(9, 8), 0.0); |
---|
154 | |
---|
155 | for (int i = 0; i<SIZE; ++i) { |
---|
156 | for (int j = 0; j<=i; ++j) { |
---|
157 | m.set(i, j, j>0 ? AP_FLOAT(i)/j : i); |
---|
158 | TEST_EXPECT_EQUAL(m.get(i, j), m.get(j, i)); |
---|
159 | } |
---|
160 | } |
---|
161 | |
---|
162 | TEST_EXPECT_EQUAL(m.get_max_value(), 9.0); |
---|
163 | TEST_EXPECT_EQUAL(m.get(9, 8), 9.0/8.0); |
---|
164 | } |
---|
165 | |
---|
166 | #endif // UNIT_TESTS |
---|
167 | |
---|
168 | // -------------------------------------------------------------------------------- |
---|