sstat 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,204 +0,0 @@
1
- #ifndef _SURVIVAL_STAT_FUNC_H_
2
- #define _SURVIVAL_STAT_FUNC_H_
3
-
4
- #include <stdio.h>
5
- #include <stdlib.h>
6
- #include "survival_def.h"
7
- #include "survival_utility.h"
8
-
9
- double precentile(double* array, int size, double target_percentile)
10
- {
11
- double percentage_each = 1.0 / size;
12
- int i;
13
- int count = 0;
14
-
15
- for (i = 1; i <= size; i++)
16
- {
17
- if ( i * percentage_each < target_percentile )
18
- {
19
- count++;
20
- } else
21
- {
22
- return array[count];
23
- }
24
- }
25
-
26
- return array[size - 1];
27
- }
28
-
29
- int index_less_equal(double* array, int size, double target)
30
- {
31
- int i;
32
-
33
- for (i = 0; i < size; i++)
34
- {
35
- if (array[i] > target)
36
- return i;
37
- }
38
-
39
- return i;
40
- }
41
-
42
- double log_rank_test(double* time_1, int* censored_1, double* time_2, int* censored_2, int size_1, int size_2)
43
- {
44
- int i, time_pnt_size;
45
- int index;
46
-
47
- array merged_time_pnts = merge_two_array(time_1, size_1, time_2, size_2);
48
- array merged_uniq_time_pnts = create_sorted_unique_array(merged_time_pnts.D_ptr, merged_time_pnts.size);
49
-
50
- //The lengths of Group_N_1 and Group_N_2 are not expected to be same. Step 1. create unique time array which inlcude time points for both
51
- Group_N Group_N_1 = group_N_given_range(time_1, censored_1, size_1, merged_uniq_time_pnts.D_ptr, merged_uniq_time_pnts.size);
52
- Group_N Group_N_2 = group_N_given_range(time_2, censored_2, size_2, merged_uniq_time_pnts.D_ptr, merged_uniq_time_pnts.size);
53
-
54
- double Z = 0;
55
- double V_i_sum = 0;
56
-
57
- Group_N combined_Group_N_1;
58
- Group_N combined_Group_N_2;
59
-
60
- combined_Group_N_1.uncensored = (int*) malloc(merged_uniq_time_pnts.size * sizeof(int));
61
- combined_Group_N_1.censored = (int*) malloc(merged_uniq_time_pnts.size * sizeof(int));
62
-
63
- combined_Group_N_2.uncensored = (int*) malloc(merged_uniq_time_pnts.size * sizeof(int));
64
- combined_Group_N_2.censored = (int*) malloc(merged_uniq_time_pnts.size * sizeof(int));
65
-
66
- //CAUTION: DO NOT SET TIME ARRAY HEERE, USE merged_uniq_time_pnts INSTEAD
67
- combined_Group_N_1.time = NULL;
68
- combined_Group_N_2.time = NULL;
69
-
70
- time_pnt_size = merged_uniq_time_pnts.size;
71
-
72
- int* N1_at_risk = (int*) malloc(time_pnt_size * sizeof(int));
73
- int* N2_at_risk = (int*) malloc(time_pnt_size * sizeof(int));
74
- int* N_i = (int*) malloc(time_pnt_size * sizeof(int));
75
- int* O_i = (int*) malloc(time_pnt_size * sizeof(int));
76
-
77
- double* E_i = (double*) malloc(time_pnt_size * sizeof(double));
78
- double* V_i = (double*) malloc(time_pnt_size * sizeof(double));
79
-
80
- //update at_risk for 1 and 2 based on combined_time_arr.
81
- for (i = 0; i < time_pnt_size; ++i)
82
- {
83
- index = find_first_index_has(Group_N_1.time, Group_N_1.size, merged_uniq_time_pnts.D_ptr[i]);
84
- if (index >= 0)
85
- {
86
- combined_Group_N_1.uncensored[i] = Group_N_1.uncensored[index];
87
- combined_Group_N_1.censored[i] = Group_N_1.censored[index];
88
- } else {
89
-
90
- combined_Group_N_1.uncensored[i] = 0;
91
- combined_Group_N_1.censored[i] = 0;
92
- }
93
- }
94
-
95
- for (i = 0; i < time_pnt_size; ++i)
96
- {
97
- index = find_first_index_has(Group_N_2.time, Group_N_2.size, merged_uniq_time_pnts.D_ptr[i]);
98
-
99
- if (index >= 0)
100
- {
101
- combined_Group_N_2.uncensored[i] = Group_N_2.uncensored[index];
102
- combined_Group_N_2.censored[i] = Group_N_2.censored[index];
103
- } else {
104
- combined_Group_N_2.uncensored[i] = 0;
105
- combined_Group_N_2.censored[i] = 0;
106
- }
107
- }
108
-
109
- N1_at_risk[0] = size_1 - combined_Group_N_1.censored[0];
110
- N2_at_risk[0] = size_2 - combined_Group_N_2.censored[0];
111
-
112
- for (i = 1; i < time_pnt_size; ++i)
113
- {
114
- N1_at_risk[i] = N1_at_risk[i - 1] - combined_Group_N_1.uncensored[i - 1] - combined_Group_N_1.censored[i];
115
- N2_at_risk[i] = N2_at_risk[i - 1] - combined_Group_N_2.uncensored[i - 1] - combined_Group_N_2.censored[i];
116
-
117
- }
118
-
119
- for (i = 0; i < time_pnt_size; ++i)
120
- {
121
- N_i[i] = N1_at_risk[i] + N2_at_risk[i];
122
- O_i[i] = (combined_Group_N_1.uncensored[i] + combined_Group_N_2.uncensored[i]);
123
- E_i[i] = 1.0 * N1_at_risk[i] * O_i[i] / N_i[i];
124
-
125
- if (N_i[i] > 1)
126
- {
127
- V_i[i] = 1.0 * O_i[i]
128
- * (1.0 * N1_at_risk[i] / N_i[i])
129
- * (1 - 1.0 * N1_at_risk[i] / N_i[i])
130
- * (N_i[i] - O_i[i]) / (N_i[i] - 1);
131
-
132
- V_i_sum += V_i[i];
133
- }
134
-
135
- Z += (combined_Group_N_1.uncensored[i] - E_i[i]);
136
- }
137
-
138
- Z = Z / sqrt(V_i_sum);
139
-
140
- free(Group_N_1.uncensored);
141
- free(Group_N_1.censored);
142
- free(Group_N_2.uncensored);
143
- free(Group_N_2.censored);
144
- free(merged_time_pnts.D_ptr);
145
- free(merged_uniq_time_pnts.D_ptr);
146
- free(N1_at_risk);
147
- free(N2_at_risk);
148
- free(N_i);
149
- free(O_i);
150
- free(E_i);
151
- free(V_i);
152
-
153
- return Z;
154
- }
155
-
156
- /*
157
- * This function does not provide a normal kaplan meier curve. A extension based on the last 3 points is applied during the calculation of KM curve
158
- */
159
- int kaplan_meier_3p_extrapolation(double* time, int* censored, int size)
160
- {
161
-
162
- Group_N at_risk = group_N_self_range(time, censored, size);
163
- puts_Group_N(&at_risk);
164
- free_Group_N(at_risk);
165
-
166
- return 0;
167
- }
168
-
169
- struct curve kaplan_meier(double* time, int* censored, int size)
170
- {
171
-
172
- int i, N;
173
-
174
- Group_N at_risk = group_N_self_range(time, censored, size);
175
-
176
- N = size;
177
-
178
- struct point* KM = (struct point*) malloc(at_risk.size * sizeof(struct point));
179
-
180
- for (i = 0; i < at_risk.size; i++)
181
- {
182
- if (i > 0)
183
- {
184
- N = (N - at_risk.uncensored[i - 1] - at_risk.censored[i - 1]);
185
- KM[i].x = at_risk.time[i];
186
- KM[i].y = 1.0 * (N - at_risk.uncensored[i] - at_risk.censored[i]) / (N - at_risk.censored[i]) * KM[i - 1].y;
187
- } else {
188
- KM[0].x = at_risk.time[i];
189
- KM[0].y = 1.0 * (N - at_risk.uncensored[0] - at_risk.censored[0]) / (N - at_risk.censored[0]);
190
- }
191
- }
192
-
193
- curve KM_curve;
194
- KM_curve.point_array = KM;
195
- KM_curve.size = at_risk.size;
196
-
197
- free(at_risk.uncensored);
198
- free(at_risk.censored);
199
- free(at_risk.time);
200
-
201
- return KM_curve;
202
- }
203
-
204
- #endif
@@ -1,293 +0,0 @@
1
- #ifndef _SURVIVAL_STAT_UTILITY_H_
2
- #define _SURVIVAL_STAT_UTILITy_H_
3
-
4
- #include <stdio.h>
5
- #include <stdlib.h>
6
- #include "global_utility.h"
7
- #include "survival_def.h"
8
- #include "type_def.h"
9
-
10
- struct array create_sorted_unique_array(double* array, int size)
11
- {
12
- struct array arr;
13
- int i;
14
- /* For performance, we have not used memset here. This might be risky */
15
- arr.D_ptr = NULL;
16
- int count;
17
-
18
- qsort(array, size, sizeof(double), &compare_double);
19
-
20
- count = 1;
21
-
22
- //calcualte number of unique
23
- for(i = 1; i < size; ++i)
24
- {
25
- if(array[i] != array[i-1])
26
- {
27
- count++;
28
- }
29
- }
30
-
31
- double * unique_arr = (double *) malloc(count * sizeof(double));
32
-
33
- //assign unique elements
34
- count = 1;
35
- unique_arr[0] = array[0];
36
- for(i = 1; i < size; ++i)
37
- {
38
- if(array[i] != array[i-1])
39
- {
40
- unique_arr[count] = array[i];
41
- count++;
42
- }
43
- }
44
-
45
- arr.D_ptr = unique_arr;
46
- arr.size = count;
47
-
48
- return arr;
49
- }
50
-
51
- array merge_two_array(double* array_1, int size_1, double* array_2, int size_2)
52
- {
53
- int i;
54
- struct array arr;
55
-
56
- //To speed up, choose to do not memset arr.
57
- arr.D_ptr = NULL;
58
-
59
- int total_size = size_1 + size_2;
60
- double * merged_array = (double *) malloc(total_size * sizeof(double));
61
- for(i = 0; i < size_1; i++)
62
- {
63
- merged_array[i] = array_1[i];
64
- }
65
-
66
- for( i = 0; i < size_2; i++)
67
- {
68
- merged_array[i + size_1] = array_2[i];
69
- }
70
-
71
- arr.D_ptr = merged_array;
72
- arr.size = total_size;
73
-
74
- return arr;
75
- }
76
-
77
- int find_first_index_has(double* arr, int size, double value)
78
- {
79
- int i;
80
- for(i = 0; i < size; i++)
81
- {
82
- if(fabs(arr[i] - value) < EPSILON)
83
- {
84
- return i;
85
- }
86
- }
87
-
88
- //no value in the array
89
- return -1;
90
- }
91
-
92
- struct Group_N group_N_self_range(double* time, int* censored, int size)
93
- {
94
- int i, count_at, uncensored_num_at, censored_num_at;
95
- double tmp, time_at;
96
-
97
- // sort time and censored based on time together, time can censored array
98
- struct point* time_censored_array = (struct point*) malloc(size * sizeof(struct point));
99
-
100
- //censored, if censored[] is positive
101
- for (i = 0; i < size; i++)
102
- {
103
- time_censored_array[i].x = time[i];
104
- if (censored[i] > 0)
105
- time_censored_array[i].y = 1;
106
- else
107
- time_censored_array[i].y = -1;
108
- }
109
-
110
- qsort(time_censored_array, size, sizeof(struct point), &point_compare_x);
111
-
112
- //count unique uncensored time point
113
- int count = 0;
114
- for (i = 0; i < size; i++)
115
- { //uncensored
116
- if (time_censored_array[i].y < 0)
117
- {
118
- if (count == 0)
119
- {
120
- count++;
121
- tmp = time_censored_array[i].x;
122
- }
123
-
124
- if (count > 0)
125
- { //unique
126
- if (time_censored_array[i].x != tmp)
127
- {
128
- count++;
129
- tmp = time_censored_array[i].x;
130
- }
131
- }
132
- }
133
- }
134
-
135
- double* unique_uncensored_time = (double *) malloc(count * sizeof(double));
136
-
137
- count = 0;
138
-
139
- for (i = 0; i < size; i++)
140
- {
141
- if (time_censored_array[i].y < 0)
142
- {
143
- if (count == 0)
144
- {
145
- count++;
146
- unique_uncensored_time[count] = time_censored_array[i].x;
147
- tmp = time_censored_array[i].x;
148
-
149
- }
150
-
151
- if (count > 0)
152
- {
153
- if (time_censored_array[i].x != tmp)
154
- {
155
- unique_uncensored_time[count] = time_censored_array[i].x;
156
-
157
- count++;
158
- tmp = time_censored_array[i].x;
159
- }
160
- }
161
- }
162
- }
163
-
164
- int* uncensored_num = (int *) malloc(count * sizeof(int));
165
- int* censored_num = (int *) malloc(count * sizeof(int));
166
-
167
- //record current time point
168
- time_at = unique_uncensored_time[0];
169
- count_at = 0;
170
- uncensored_num_at = 0;
171
- censored_num_at = 0;
172
-
173
- for (i = 0; i < size; i++)
174
- {
175
- if (time_censored_array[i].x <= time_at)
176
- {
177
- if (time_censored_array[i].y > 0)
178
- censored_num_at++;
179
- else
180
- uncensored_num_at++;
181
-
182
- if (i == size - 1)
183
- {
184
- uncensored_num[count_at] = uncensored_num_at;
185
- censored_num[count_at] = censored_num_at;
186
- }
187
-
188
- } else {
189
- uncensored_num[count_at] = uncensored_num_at;
190
- censored_num[count_at] = censored_num_at;
191
- count_at++;
192
-
193
- uncensored_num_at = 0;
194
- censored_num_at = 0;
195
- time_at = unique_uncensored_time[count_at];
196
-
197
- if (time_censored_array[i].y > 0)
198
- censored_num_at++;
199
- else
200
- uncensored_num_at++;
201
- }
202
- }
203
-
204
- Group_N at_risk_result;
205
- at_risk_result.uncensored = uncensored_num;
206
- at_risk_result.censored = censored_num;
207
- at_risk_result.size = count;
208
- at_risk_result.time = unique_uncensored_time;
209
- free(time_censored_array);
210
- return at_risk_result;
211
- }
212
-
213
- struct Group_N group_N_given_range(double* time, int* censored, int size, double* unique_time, int unique_time_size)
214
- {
215
- int i, count_at, uncensored_num_at, censored_num_at;
216
- double time_at;
217
-
218
- struct point* time_censored_array = (struct point*) malloc(size * sizeof(struct point));
219
-
220
- for (i = 0; i < size; i++)
221
- {
222
- time_censored_array[i].x = time[i];
223
- //not very fast here, prefer to define another point
224
- if (censored[i] > 0)
225
- time_censored_array[i].y = 1;
226
- else
227
- time_censored_array[i].y = -1;
228
- }
229
-
230
- qsort(time_censored_array, size, sizeof(struct point), &point_compare_x);
231
-
232
- int* uncensored_num = (int *) malloc(unique_time_size * sizeof(int));
233
- int* censored_num = (int *) malloc(unique_time_size * sizeof(int));
234
-
235
- for (i = 0; i < unique_time_size; i++)
236
- {
237
- uncensored_num[i] = 0;
238
- censored_num[i] = 0;
239
- }
240
-
241
- //record current time point
242
- time_at = unique_time[0];
243
- count_at = 0;
244
- uncensored_num_at = 0;
245
- censored_num_at = 0;
246
-
247
- for (i = 0; i < size; i++)
248
- {
249
- if (time_censored_array[i].x <= time_at)
250
- {
251
- if (time_censored_array[i].y > 0)
252
- censored_num_at++;
253
- else
254
- uncensored_num_at++;
255
-
256
- if (i == size - 1)
257
- {
258
- uncensored_num[count_at] = uncensored_num_at;
259
- censored_num[count_at] = censored_num_at;
260
- }
261
-
262
- } else {
263
-
264
- while (time_censored_array[i].x > time_at)
265
- {
266
- uncensored_num[count_at] = uncensored_num_at;
267
- censored_num[count_at] = censored_num_at;
268
- count_at++;
269
-
270
- uncensored_num_at = 0;
271
- censored_num_at = 0;
272
- time_at = unique_time[count_at];
273
- }
274
-
275
- if (time_censored_array[i].y > 0)
276
- censored_num_at++;
277
- else
278
- uncensored_num_at++;
279
- }
280
- }
281
-
282
- Group_N at_risk_result;
283
- at_risk_result.uncensored = uncensored_num;
284
- at_risk_result.censored = censored_num;
285
- at_risk_result.size = unique_time_size;
286
- at_risk_result.time = unique_time;
287
-
288
- free(time_censored_array);
289
-
290
- return at_risk_result;
291
- }
292
-
293
- #endif