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.
- checksums.yaml +4 -4
- data/ext/sstat/lib/survival.tar.gz +0 -0
- data/ext/sstat/lib/survival/survival_kaplan_meier.h +89 -22
- data/ext/sstat/sstat.c +192 -181
- data/ext/sstat/sstat.h +13 -0
- data/ext/sstat/sstat.o +0 -0
- data/ext/sstat/sstat.so +0 -0
- data/lib/sstat.o +0 -0
- data/lib/sstat.so +0 -0
- metadata +4 -12
- data/ext/extconf.rb +0 -4
- data/ext/lib/distribution.h +0 -274
- data/ext/lib/global_utility.h +0 -17
- data/ext/lib/survival.h +0 -6
- data/ext/lib/survival_def.h +0 -49
- data/ext/lib/survival_func.h +0 -204
- data/ext/lib/survival_utility.h +0 -293
- data/ext/lib/type_def.h +0 -35
- data/ext/sstat/lib/basic/log +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2f0ea54fb1319bd5702f17df6fc58c5ae6f67ddf
|
|
4
|
+
data.tar.gz: bf10d230f11b7bac1888d9eb77c661ed6c597ee1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 51fe68035f95e4ee76cff316190a74ba910a40b0586bfd1207055d238ab4c6ab3003a10723b5366f4dafc4a7f862562ee75275f70283a7a03895d144f63e89b2
|
|
7
|
+
data.tar.gz: dc192a0ce719ff00141f6578956aa12c619d7519548993665f8050b2e7defdc200120f20cc581a467d9d534e8c5f168553ab00512074ea824b7cedddc5581de2
|
|
Binary file
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* @param censored censored information: positive -> censored; zero or negative -> uncensored
|
|
12
12
|
* @return CENS_UC_NUM structure
|
|
13
13
|
*/
|
|
14
|
+
#define EXP 1e-12
|
|
14
15
|
int censored_uncensred_each_time_range(double* time, int* censored, int size, struct CENS_UC_NUM** cens_ucens_number)
|
|
15
16
|
{
|
|
16
17
|
int i, count_at, uncensored_num_at, censored_num_at;
|
|
@@ -193,18 +194,30 @@ int kaplan_meier(double* time, int* censored, int size, curve* KM_curve)
|
|
|
193
194
|
/**
|
|
194
195
|
* @brief extend the KM curve based on the last 3 points
|
|
195
196
|
*/
|
|
196
|
-
int KM_3p_extrapolation(struct CENS_UC_NUM** cens_uc_num, struct CENS_UC_NUM** updated_cens_uc_num, int sample_size)
|
|
197
|
+
int KM_3p_extrapolation(struct CENS_UC_NUM** cens_uc_num, struct CENS_UC_NUM ** updated_cens_uc_num, int sample_size)
|
|
197
198
|
{
|
|
198
|
-
|
|
199
|
-
|
|
199
|
+
int mean_last_uncensored = 0;
|
|
200
|
+
int mean_last_censored = 0;
|
|
200
201
|
double time_interval_mean = 0;
|
|
202
|
+
|
|
201
203
|
int num_left = 0;
|
|
204
|
+
int num_left_copy = 0;
|
|
205
|
+
|
|
206
|
+
/*Track break point during pre-mapping */
|
|
207
|
+
int is_break_at_uncensored = 0;
|
|
208
|
+
|
|
209
|
+
/*Track break point during pre-mapping */
|
|
210
|
+
int is_break_at_censored = 0;
|
|
211
|
+
|
|
202
212
|
int used_sample_num = 0;
|
|
203
213
|
int extrapolation_size = 0;
|
|
204
214
|
int updated_cens_uc_num_size = 0;
|
|
205
215
|
int i;
|
|
206
216
|
int last_1_index = (*cens_uc_num)->size - 2;
|
|
207
217
|
int last_4_index = (*cens_uc_num)->size - 5;
|
|
218
|
+
int actual_updated_size = 0;
|
|
219
|
+
int count = 0;
|
|
220
|
+
int extra = 0;
|
|
208
221
|
|
|
209
222
|
/* calculate the total number (censored and uncensored) already used */
|
|
210
223
|
for(i = 0; i < (*cens_uc_num)->size; i ++)
|
|
@@ -216,6 +229,7 @@ int KM_3p_extrapolation(struct CENS_UC_NUM** cens_uc_num, struct CENS_UC_NUM** u
|
|
|
216
229
|
/* TODO should error check here */
|
|
217
230
|
num_left = sample_size - used_sample_num;
|
|
218
231
|
|
|
232
|
+
/*Calculate the mean for uncensored, censored and time interval */
|
|
219
233
|
for(i = 0; i < 3; i++)
|
|
220
234
|
{
|
|
221
235
|
/*
|
|
@@ -231,16 +245,68 @@ int KM_3p_extrapolation(struct CENS_UC_NUM** cens_uc_num, struct CENS_UC_NUM** u
|
|
|
231
245
|
}
|
|
232
246
|
|
|
233
247
|
time_interval_mean = (*cens_uc_num)->time[last_1_index] - (*cens_uc_num)->time[last_4_index];
|
|
234
|
-
mean_last_uncensored = mean_last_uncensored / 3;
|
|
235
|
-
mean_last_censored = mean_last_censored / 3;
|
|
248
|
+
mean_last_uncensored = (int)floor(mean_last_uncensored / 3);
|
|
249
|
+
mean_last_censored = (int)floor(mean_last_censored / 3);
|
|
250
|
+
|
|
236
251
|
time_interval_mean = time_interval_mean / 3;
|
|
237
252
|
|
|
238
253
|
/* Calculate how many points we should extrapolate */
|
|
239
254
|
extrapolation_size = ceil((double)num_left / (mean_last_uncensored + mean_last_censored));
|
|
255
|
+
|
|
240
256
|
updated_cens_uc_num_size = (*cens_uc_num)->size + extrapolation_size;
|
|
241
257
|
|
|
242
|
-
|
|
258
|
+
/*If both mean_last_uncensored and mean_last_censored are zero return copy cens_uc_num to updated_cens_uc_num */
|
|
259
|
+
if(mean_last_uncensored < EXP && mean_last_censored < EXP) {
|
|
260
|
+
check(alloc_CENS_UC_NUM(updated_cens_uc_num, (*cens_uc_num)->size) == 0, "Failed in allocating CENS_UC_NUM structure");
|
|
261
|
+
/* Create a copy for the original cens_uc_num struct */
|
|
262
|
+
for(i = 0; i < (*cens_uc_num)->size; i++)
|
|
263
|
+
{
|
|
264
|
+
(*updated_cens_uc_num)->censored[i] = (*cens_uc_num)->censored[i];
|
|
265
|
+
(*updated_cens_uc_num)->uncensored[i] = (*cens_uc_num)->uncensored[i];
|
|
266
|
+
(*updated_cens_uc_num)->time[i] = (*cens_uc_num)->time[i];
|
|
267
|
+
}
|
|
268
|
+
return 0;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
num_left_copy = num_left;
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
/* Pre-mapping to find the actual extrapolation number */
|
|
275
|
+
while(num_left_copy >= 0) {
|
|
276
|
+
num_left_copy = num_left_copy - mean_last_uncensored;
|
|
277
|
+
count++;
|
|
278
|
+
if(num_left_copy >= 0) {
|
|
279
|
+
is_break_at_uncensored = 0;
|
|
280
|
+
extra = num_left_copy;
|
|
281
|
+
} else {
|
|
282
|
+
is_break_at_uncensored = 1;
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
num_left_copy = num_left_copy - mean_last_censored;
|
|
287
|
+
|
|
288
|
+
if(num_left_copy > 0) {
|
|
289
|
+
is_break_at_censored = 0;
|
|
290
|
+
extra = num_left_copy;
|
|
291
|
+
} else {
|
|
292
|
+
is_break_at_censored = 1;
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if(num_left_copy == 0) {
|
|
297
|
+
is_break_at_uncensored = 0;
|
|
298
|
+
is_break_at_censored = 0;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
243
302
|
|
|
303
|
+
//printf("Actual size, number left: %i, %i %i, %i, \n", count, num_left, mean_last_uncensored, mean_last_censored);
|
|
304
|
+
|
|
305
|
+
actual_updated_size = (*cens_uc_num)->size + count;
|
|
306
|
+
|
|
307
|
+
check(alloc_CENS_UC_NUM(updated_cens_uc_num, actual_updated_size) == 0, "Failed in allocating CENS_UC_NUM structure");
|
|
308
|
+
|
|
309
|
+
/* Create a copy for the original cens_uc_num struct */
|
|
244
310
|
for(i = 0; i < (*cens_uc_num)->size; i++)
|
|
245
311
|
{
|
|
246
312
|
(*updated_cens_uc_num)->censored[i] = (*cens_uc_num)->censored[i];
|
|
@@ -248,24 +314,25 @@ int KM_3p_extrapolation(struct CENS_UC_NUM** cens_uc_num, struct CENS_UC_NUM** u
|
|
|
248
314
|
(*updated_cens_uc_num)->time[i] = (*cens_uc_num)->time[i];
|
|
249
315
|
}
|
|
250
316
|
|
|
251
|
-
for(i = (*cens_uc_num)->size; i <
|
|
252
|
-
{
|
|
317
|
+
for(i = (*cens_uc_num)->size; i < actual_updated_size; i++) {
|
|
253
318
|
(*updated_cens_uc_num)->time[i] = (*updated_cens_uc_num)->time[i-1] + time_interval_mean;
|
|
319
|
+
if(i == actual_updated_size -1) {
|
|
320
|
+
|
|
321
|
+
if(is_break_at_uncensored) {
|
|
322
|
+
(*updated_cens_uc_num)->uncensored[i] = extra;
|
|
323
|
+
(*updated_cens_uc_num)->censored[i] = 0;
|
|
324
|
+
} else if(is_break_at_censored) {
|
|
325
|
+
(*updated_cens_uc_num)->uncensored[i] = mean_last_uncensored;
|
|
326
|
+
(*updated_cens_uc_num)->censored[i] = extra;
|
|
327
|
+
} else {
|
|
328
|
+
(*updated_cens_uc_num)->uncensored[i] = mean_last_censored;
|
|
329
|
+
(*updated_cens_uc_num)->censored[i] = mean_last_uncensored;
|
|
330
|
+
}
|
|
254
331
|
|
|
255
|
-
|
|
256
|
-
(*updated_cens_uc_num)->uncensored[i] =
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
/* We update the num_left to make sure that the total number of samples in the extrapolation group cannot be larger than the total number of samples */
|
|
261
|
-
num_left = num_left - mean_last_uncensored;
|
|
262
|
-
|
|
263
|
-
if (mean_last_censored<num_left)
|
|
264
|
-
(*updated_cens_uc_num)->censored[i] = mean_last_censored;
|
|
265
|
-
else
|
|
266
|
-
(*updated_cens_uc_num)->censored[i] = num_left;
|
|
267
|
-
|
|
268
|
-
num_left = num_left - mean_last_censored;
|
|
332
|
+
} else {
|
|
333
|
+
(*updated_cens_uc_num)->uncensored[i] = mean_last_censored;
|
|
334
|
+
(*updated_cens_uc_num)->censored[i] = mean_last_uncensored;
|
|
335
|
+
}
|
|
269
336
|
}
|
|
270
337
|
|
|
271
338
|
return 0;
|
data/ext/sstat/sstat.c
CHANGED
|
@@ -2,228 +2,239 @@
|
|
|
2
2
|
|
|
3
3
|
static VALUE rb_percentile(VALUE self, VALUE array, VALUE target)
|
|
4
4
|
{
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
5
|
+
int size = RARRAY_LEN(array);
|
|
6
|
+
int i;
|
|
7
|
+
double _target = NUM2DBL(target);
|
|
8
|
+
double _percentile;
|
|
9
|
+
double* c_array = (double *)malloc(sizeof(double) * size);
|
|
10
|
+
|
|
11
|
+
for (i = 0; i < size; i++) {
|
|
12
|
+
c_array[i] = NUM2DBL(rb_ary_entry(array, i));
|
|
13
|
+
}
|
|
14
|
+
_percentile = precentile(c_array, size, _target);
|
|
15
|
+
free(c_array);
|
|
16
|
+
|
|
17
|
+
return DBL2NUM(_percentile);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
static VALUE rb_percentile_index(VALUE self, VALUE array, VALUE target)
|
|
21
21
|
{
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
22
|
+
int size = RARRAY_LEN(array);
|
|
23
|
+
int i;
|
|
24
|
+
double _target = NUM2DBL(target);
|
|
25
|
+
int _percentile_index;
|
|
26
|
+
double* c_array = (double *)malloc(sizeof(double) * size);
|
|
27
|
+
|
|
28
|
+
for (i = 0; i < size; i++) {
|
|
29
|
+
c_array[i] = NUM2DBL(rb_ary_entry(array, i));
|
|
30
|
+
}
|
|
31
|
+
_percentile_index = precentile_index(c_array, size, _target);
|
|
32
|
+
free(c_array);
|
|
33
|
+
|
|
34
|
+
return INT2NUM(_percentile_index);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
static VALUE rb_index_less_equal(VALUE self, VALUE array, VALUE target)
|
|
38
38
|
{
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
int size = RARRAY_LEN(array);
|
|
40
|
+
int i;
|
|
41
|
+
int _index;
|
|
42
|
+
double _target = NUM2DBL(target);
|
|
43
|
+
double* c_array = (double *)malloc(sizeof(double) * size);
|
|
44
|
+
for (i = 0; i < size; i++) {
|
|
45
|
+
c_array[i] = NUM2DBL(rb_ary_entry(array, i));
|
|
46
|
+
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
_index = index_less_equal(c_array, size, _target);
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
free(c_array);
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
return INT2NUM(_index);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
static VALUE rb_hist_mean(VALUE self, VALUE bin, VALUE range)
|
|
56
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
|
-
|
|
57
|
+
int bin_size = RARRAY_LEN(bin);
|
|
58
|
+
int range_size = RARRAY_LEN(range);
|
|
59
|
+
int i;
|
|
60
|
+
|
|
61
|
+
if ((range_size - bin_size) != 1)
|
|
62
|
+
rb_raise(rb_eTypeError, "Size of range should be 1 larger than size of bin.");
|
|
63
|
+
|
|
64
|
+
double hmean = 0;
|
|
65
|
+
struct histogram* h = (struct histogram*)malloc(sizeof(struct histogram));
|
|
66
|
+
h->n = bin_size;
|
|
67
|
+
h->range = malloc(sizeof(double) * ( h->n + 1));
|
|
68
|
+
h->bin = malloc(sizeof(double) * (h->n));
|
|
69
|
+
|
|
70
|
+
for (i = 0; i < bin_size; i++) {
|
|
71
|
+
h->bin[i] = NUM2DBL(rb_ary_entry(bin, i));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
for (i = 0; i < range_size; i++) {
|
|
75
|
+
h->range[i] = NUM2DBL(rb_ary_entry(range, i));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
histogram_mean(h, &hmean);
|
|
79
|
+
free_histogram(h);
|
|
80
|
+
return DBL2NUM(hmean);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
static VALUE rb_hist_median(VALUE self, VALUE bin, VALUE range)
|
|
84
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
|
-
|
|
85
|
+
int bin_size = RARRAY_LEN(bin);
|
|
86
|
+
int range_size = RARRAY_LEN(range);
|
|
87
|
+
int i;
|
|
88
|
+
|
|
89
|
+
if ((range_size - bin_size) != 1)
|
|
90
|
+
rb_raise(rb_eTypeError, "Size of range should be 1 larger than size of bin.");
|
|
91
|
+
|
|
92
|
+
double hmedian = 0;
|
|
93
|
+
struct histogram* h = (struct histogram*)malloc(sizeof(struct histogram));
|
|
94
|
+
h->n = bin_size;
|
|
95
|
+
h->range = malloc(sizeof(double) * ( h->n + 1));
|
|
96
|
+
h->bin = malloc(sizeof(double) * (h->n));
|
|
97
|
+
|
|
98
|
+
for (i = 0; i < bin_size; i++) {
|
|
99
|
+
h->bin[i] = NUM2DBL(rb_ary_entry(bin, i));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
for (i = 0; i < range_size; i++) {
|
|
103
|
+
h->range[i] = NUM2DBL(rb_ary_entry(range, i));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
histogram_median(h, &hmedian);
|
|
107
|
+
free_histogram(h);
|
|
108
|
+
return DBL2NUM(hmedian);
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
static VALUE rb_kaplan_meier(VALUE self, VALUE time, VALUE censored)
|
|
112
112
|
{
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
proc_status = kaplan_meier(_time, _censored, size, &KM_curve);
|
|
127
|
-
if (proc_status == 0 )
|
|
128
|
-
{
|
|
129
|
-
VALUE KM_x = rb_ary_new2(KM_curve.size);
|
|
130
|
-
VALUE KM_y = rb_ary_new2(KM_curve.size);
|
|
131
|
-
|
|
132
|
-
for (i = 0; i < KM_curve.size; i++)
|
|
133
|
-
{
|
|
134
|
-
rb_ary_store(KM_x, i, DBL2NUM(KM_curve.point_array[i].x));
|
|
135
|
-
rb_ary_store(KM_y, i, DBL2NUM(KM_curve.point_array[i].y));
|
|
113
|
+
int size = RARRAY_LEN(time);
|
|
114
|
+
int i;
|
|
115
|
+
struct curve KM_curve;
|
|
116
|
+
int proc_status;
|
|
117
|
+
VALUE result;
|
|
118
|
+
double* _time = (double *)malloc(sizeof(double) * size);
|
|
119
|
+
int* _censored = (int *)malloc(sizeof(int) * size);
|
|
120
|
+
for (i = 0; i < size; i++) {
|
|
121
|
+
_time[i] = NUM2DBL(rb_ary_entry(time, i));
|
|
122
|
+
|
|
123
|
+
_censored[i] = NUM2INT(rb_ary_entry(censored, i));
|
|
136
124
|
}
|
|
137
125
|
|
|
138
|
-
|
|
126
|
+
proc_status = kaplan_meier(_time, _censored, size, &KM_curve);
|
|
127
|
+
if (proc_status == 0 )
|
|
128
|
+
{
|
|
129
|
+
VALUE KM_x = rb_ary_new2(KM_curve.size);
|
|
130
|
+
VALUE KM_y = rb_ary_new2(KM_curve.size);
|
|
131
|
+
|
|
132
|
+
for (i = 0; i < KM_curve.size; i++)
|
|
133
|
+
{
|
|
134
|
+
rb_ary_store(KM_x, i, DBL2NUM(KM_curve.point_array[i].x));
|
|
135
|
+
rb_ary_store(KM_y, i, DBL2NUM(KM_curve.point_array[i].y));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
result = rb_hash_new();
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
rb_hash_aset(result, rb_str_new2("time"), KM_x);
|
|
141
|
+
rb_hash_aset(result, rb_str_new2("prob"), KM_y);
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
143
|
+
free(_time);
|
|
144
|
+
free(_censored);
|
|
145
|
+
free(KM_curve.point_array);
|
|
146
|
+
return result;
|
|
147
|
+
} else {
|
|
148
|
+
return Qfalse;
|
|
149
|
+
}
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
static VALUE rb_kaplan_meier_3p_extraploation(VALUE self, VALUE time, VALUE censored)
|
|
153
153
|
{
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
proc_status = kaplan_meier_3p_extrapolation(_time, _censored, size, &KM_curve);
|
|
168
|
-
if (proc_status == 0 )
|
|
169
|
-
{
|
|
170
|
-
VALUE KM_x = rb_ary_new2(KM_curve.size);
|
|
171
|
-
VALUE KM_y = rb_ary_new2(KM_curve.size);
|
|
154
|
+
int size = RARRAY_LEN(time);
|
|
155
|
+
int i;
|
|
156
|
+
struct curve KM_curve;
|
|
157
|
+
int proc_status;
|
|
158
|
+
VALUE result;
|
|
159
|
+
double* _time = (double *)malloc(sizeof(double) * size);
|
|
160
|
+
int* _censored = (int *)malloc(sizeof(int) * size);
|
|
161
|
+
for (i = 0; i < size; i++) {
|
|
162
|
+
_time[i] = NUM2DBL(rb_ary_entry(time, i));
|
|
163
|
+
|
|
164
|
+
_censored[i] = NUM2INT(rb_ary_entry(censored, i));
|
|
165
|
+
}
|
|
172
166
|
|
|
173
|
-
|
|
167
|
+
proc_status = kaplan_meier_3p_extrapolation(_time, _censored, size, &KM_curve);
|
|
168
|
+
if (proc_status == 0 )
|
|
174
169
|
{
|
|
175
|
-
|
|
176
|
-
|
|
170
|
+
VALUE KM_x = rb_ary_new2(KM_curve.size);
|
|
171
|
+
VALUE KM_y = rb_ary_new2(KM_curve.size);
|
|
172
|
+
|
|
173
|
+
for (i = 0; i < KM_curve.size; i++)
|
|
174
|
+
{
|
|
175
|
+
rb_ary_store(KM_x, i, DBL2NUM(KM_curve.point_array[i].x));
|
|
176
|
+
rb_ary_store(KM_y, i, DBL2NUM(KM_curve.point_array[i].y));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
result = rb_hash_new();
|
|
180
|
+
|
|
181
|
+
rb_hash_aset(result, rb_str_new2("time"), KM_x);
|
|
182
|
+
rb_hash_aset(result, rb_str_new2("prob"), KM_y);
|
|
183
|
+
|
|
184
|
+
free(_time);
|
|
185
|
+
free(_censored);
|
|
186
|
+
//free(KM_curve.point_array);
|
|
187
|
+
return result;
|
|
188
|
+
} else {
|
|
189
|
+
return Qfalse;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
static VALUE rb_log_rank_test(VALUE self, VALUE _time_1, VALUE _cens_1, VALUE _time_2, VALUE _cens_2)
|
|
194
|
+
{
|
|
195
|
+
int size_1 = RARRAY_LEN(_time_1);
|
|
196
|
+
int size_2 = RARRAY_LEN(_time_2);
|
|
197
|
+
|
|
198
|
+
int i;
|
|
199
|
+
double _Z;
|
|
200
|
+
|
|
201
|
+
double* time_1 = (double *)malloc(sizeof(double) * size_1);
|
|
202
|
+
double* time_2 = (double *)malloc(sizeof(double) * size_2);
|
|
203
|
+
int* cens_1 = (int *)malloc(sizeof(int) * size_1);
|
|
204
|
+
int* cens_2 = (int *)malloc(sizeof(int) * size_2);
|
|
205
|
+
for (i = 0; i < size_1; i++) {
|
|
206
|
+
time_1[i] = NUM2DBL(rb_ary_entry(_time_1, i));
|
|
207
|
+
cens_1[i] = NUM2INT(rb_ary_entry(_cens_1, i));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
for (i = 0; i < size_2; i++) {
|
|
211
|
+
time_2[i] = NUM2DBL(rb_ary_entry(_time_2, i));
|
|
212
|
+
cens_2[i] = NUM2INT(rb_ary_entry(_cens_2, i));
|
|
177
213
|
}
|
|
178
214
|
|
|
179
|
-
|
|
215
|
+
_Z = log_rank_test(time_1, cens_1, time_2, cens_2, size_1, size_2);
|
|
180
216
|
|
|
181
|
-
|
|
182
|
-
|
|
217
|
+
free(time_1);
|
|
218
|
+
free(time_2);
|
|
219
|
+
free(cens_1);
|
|
220
|
+
free(cens_2);
|
|
183
221
|
|
|
184
|
-
|
|
185
|
-
free(_censored);
|
|
186
|
-
//free(KM_curve.point_array);
|
|
187
|
-
return result;
|
|
188
|
-
} else {
|
|
189
|
-
return Qfalse;
|
|
190
|
-
}
|
|
222
|
+
return DBL2NUM(_Z);
|
|
191
223
|
}
|
|
192
224
|
|
|
193
|
-
static VALUE
|
|
225
|
+
static VALUE rb_cdf_unormal_Q(VALUE self, VALUE x)
|
|
194
226
|
{
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
int i;
|
|
199
|
-
double _Z;
|
|
200
|
-
|
|
201
|
-
double* time_1 = (double *)malloc(sizeof(double) * size_1);
|
|
202
|
-
double* time_2 = (double *)malloc(sizeof(double) * size_2);
|
|
203
|
-
int* cens_1 = (int *)malloc(sizeof(int) * size_1);
|
|
204
|
-
int* cens_2 = (int *)malloc(sizeof(int) * size_2);
|
|
205
|
-
for (i = 0; i < size_1; i++) {
|
|
206
|
-
time_1[i] = NUM2DBL(rb_ary_entry(_time_1, i));
|
|
207
|
-
cens_1[i] = NUM2INT(rb_ary_entry(_cens_1, i));
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
for (i = 0; i < size_2; i++) {
|
|
211
|
-
time_2[i] = NUM2DBL(rb_ary_entry(_time_2, i));
|
|
212
|
-
cens_2[i] = NUM2INT(rb_ary_entry(_cens_2, i));
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
_Z = log_rank_test(time_1, cens_1, time_2, cens_2, size_1, size_2);
|
|
216
|
-
|
|
217
|
-
free(time_1);
|
|
218
|
-
free(time_2);
|
|
219
|
-
free(cens_1);
|
|
220
|
-
free(cens_2);
|
|
221
|
-
|
|
222
|
-
return DBL2NUM(_Z);
|
|
227
|
+
double Q = cdf_ugaussian_Q(NUM2DBL(x));
|
|
228
|
+
return DBL2NUM(Q);
|
|
223
229
|
}
|
|
224
230
|
|
|
225
|
-
static VALUE
|
|
231
|
+
static VALUE rb_dist_chi_square_Q(VALUE self, VALUE index, VALUE degree)
|
|
226
232
|
{
|
|
227
|
-
|
|
228
|
-
|
|
233
|
+
return 0;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
static VALUE rb_dist_chi_square_P(VALUE self, VALUE index, VALUE degree)
|
|
237
|
+
{
|
|
238
|
+
return 0;
|
|
239
|
+
|
|
229
240
|
}
|