File Coverage

CaseResampling.xs
Criterion Covered Total %
statement 99 166 59.6
branch 38 80 47.5
condition n/a
subroutine n/a
pod n/a
total 137 246 55.6


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT /* we want efficiency */
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5              
6             #include "ppport.h"
7              
8             #include "mt.h"
9             #include "stats.h"
10             #include
11              
12              
13             typedef struct mt * Statistics__CaseResampling__RdGen;
14              
15             void*
16 0           U32ArrayPtr (pTHX_ int n)
17             {
18 0           SV * sv = sv_2mortal( NEWSV( 0, n*sizeof(U32) ) );
19 0           return SvPVX(sv);
20             }
21              
22             double
23 2           cs_mean_av(pTHX_ AV* sample)
24             {
25             I32 i, n;
26             SV** elem;
27             double sum;
28 2           n = av_len(sample)+1;
29 2           sum = 0.;
30 20 100         for (i = 0; i < n; ++i) {
31 18 50         if (NULL == (elem = av_fetch(sample, i, 0))) {
32 0           croak("Could not fetch element from array");
33             }
34             else
35 18           sum += SvNV(*elem);
36             }
37 2           return sum/(double)n;
38             }
39              
40             double
41 2           cs_sum_deviation_squared_av(pTHX_ double mean, AV* sample)
42             {
43             I32 i, n;
44             SV** elem;
45             double sum;
46 2           n = av_len(sample)+1;
47 2           sum = 0.;
48 16 100         for (i = 0; i < n; ++i) {
49 14 50         if (NULL == (elem = av_fetch(sample, i, 0))) {
50 0           croak("Could not fetch element from array");
51             }
52             else
53 14           sum += pow(SvNV(*elem)-mean, 2);
54             }
55 2           return sum;
56             }
57              
58             void
59 44           avToCAry(pTHX_ AV* in, double** out, I32* n)
60             {
61             I32 thisN;
62             double* ary;
63             SV** elem;
64             I32 i;
65 44           thisN = av_len(in)+1;
66 44           *n = thisN;
67 44 50         if (thisN == 0)
68 0           return;
69              
70 44           Newx(ary, thisN, double);
71 44           *out = ary;
72 273 100         for (i = 0; i < thisN; ++i) {
73 229 50         if (NULL == (elem = av_fetch(in, i, 0))) {
74 0           Safefree(ary);
75 0           croak("Could not fetch element from array");
76             }
77             else
78 229           ary[i] = SvNV(*elem);
79             }
80             }
81              
82             void
83 1           cAryToAV(pTHX_ double* in, AV** out, I32 n)
84             {
85             SV* elem;
86             I32 i;
87 1           *out = newAV();
88 1 50         if (n == 0)
89 0           return;
90              
91 1           av_extend(*out, n-1);
92              
93 12 100         for (i = 0; i < n; ++i) {
94 11           elem = newSVnv(in[i]);
95 11 50         if (NULL == av_store(*out, i, elem))
96 0           SvREFCNT_dec(elem);
97             }
98             }
99              
100             struct mt*
101 3           get_rnd(pTHX)
102             {
103             IV tmp;
104 3           SV* therndsv = get_sv("Statistics::CaseResampling::Rnd", 0);
105 3 50         if (therndsv == NULL
106 3 50         || !SvROK(therndsv)
107 3 50         || !sv_derived_from(therndsv, "Statistics::CaseResampling::RdGen"))
108             {
109 0           croak("Random number generator not set up!");
110             }
111 3           tmp = SvIV((SV*)SvRV(therndsv));
112 3           return INT2PTR(struct mt*, tmp);
113             }
114              
115              
116             MODULE = Statistics::CaseResampling PACKAGE = Statistics::CaseResampling
117             PROTOTYPES: DISABLE
118              
119             INCLUDE: RdGen.xs.inc
120              
121             MODULE = Statistics::CaseResampling PACKAGE = Statistics::CaseResampling
122             PROTOTYPES: DISABLE
123              
124             AV*
125             resample(sample)
126             AV* sample
127             PREINIT:
128             I32 nelem;
129             double* csample;
130             double* destsample;
131             struct mt* rnd;
132             CODE:
133 1           rnd = get_rnd(aTHX);
134 1           avToCAry(aTHX_ sample, &csample, &nelem);
135 1 50         if (nelem != 0) {
136 1           Newx(destsample, nelem, double);
137 1           do_resample(csample, nelem, rnd, destsample);
138 1           cAryToAV(aTHX_ destsample, &RETVAL, nelem);
139 1           Safefree(destsample);
140             }
141             else
142 0           RETVAL = newAV();
143 1           Safefree(csample);
144 1           sv_2mortal((SV*)RETVAL);
145             OUTPUT: RETVAL
146              
147              
148             AV*
149             resample_medians(sample, runs)
150             AV* sample
151             I32 runs
152             PREINIT:
153             I32 nelem;
154             I32 i_run;
155             double* csample;
156             double* destsample;
157             struct mt* rnd;
158             CODE:
159 1           rnd = get_rnd(aTHX);
160 1           avToCAry(aTHX_ sample, &csample, &nelem);
161 1           RETVAL = newAV();
162 1 50         if (nelem != 0) {
163 1           Newx(destsample, nelem, double);
164 1           av_extend(RETVAL, runs-1);
165 31 100         for (i_run = 0; i_run < runs; ++i_run) {
166 30           do_resample(csample, nelem, rnd, destsample);
167 30           av_store(RETVAL, i_run, newSVnv(cs_median(destsample, nelem)));
168             }
169 1           Safefree(destsample);
170             }
171 1           Safefree(csample);
172 1           sv_2mortal((SV*)RETVAL);
173             OUTPUT: RETVAL
174              
175              
176             AV*
177             resample_means(sample, runs)
178             AV* sample
179             I32 runs
180             PREINIT:
181             I32 nelem;
182             I32 i_run;
183             double* csample;
184             double* destsample;
185             struct mt* rnd;
186             CODE:
187 1           rnd = get_rnd(aTHX);
188 1           avToCAry(aTHX_ sample, &csample, &nelem);
189 1           RETVAL = newAV();
190 1 50         if (nelem != 0) {
191 1           Newx(destsample, nelem, double);
192 1           av_extend(RETVAL, runs-1);
193 31 100         for (i_run = 0; i_run < runs; ++i_run) {
194 30           do_resample(csample, nelem, rnd, destsample);
195 30           av_store(RETVAL, i_run, newSVnv(cs_mean(destsample, nelem)));
196             }
197 1           Safefree(destsample);
198             }
199 1           Safefree(csample);
200 1           sv_2mortal((SV*)RETVAL);
201             OUTPUT: RETVAL
202              
203              
204             double
205             median(sample)
206             AV* sample
207             PREINIT:
208             I32 nelem;
209             double* csample;
210             CODE:
211 23           avToCAry(aTHX_ sample, &csample, &nelem);
212 23 50         if (nelem == 0)
213 0           RETVAL = 0.;
214             else
215 23           RETVAL = cs_median(csample, nelem);
216 23           Safefree(csample);
217             OUTPUT: RETVAL
218              
219             double
220             median_absolute_deviation(sample)
221             AV* sample
222             PREINIT:
223             I32 nelem;
224             double* csample;
225             CODE:
226 1           avToCAry(aTHX_ sample, &csample, &nelem);
227 1 50         if (nelem == 0)
228 0           RETVAL = 0.;
229             else {
230             unsigned int i;
231             double* absdev;
232              
233 1           const double median = cs_median(csample, nelem);
234             /* in principle, I think one could write an algorithm
235             * that doesn't require mallocing the second array by inlining an
236             * O(n) median that visits each element only once? */
237 1           absdev = (double*)malloc(nelem * sizeof(double));
238 12 100         for (i = 0; i < nelem; ++i)
239 11           absdev[i] = fabs(csample[i] - median);
240 1           RETVAL = cs_median(absdev, nelem);
241 1           free(absdev);
242             }
243 1           Safefree(csample);
244             OUTPUT: RETVAL
245              
246              
247             double
248             first_quartile(sample)
249             AV* sample
250             PREINIT:
251             I32 nelem;
252             double* csample;
253             CODE:
254 0           avToCAry(aTHX_ sample, &csample, &nelem);
255 0 0         if (nelem == 0)
256 0           RETVAL = 0.;
257             else
258 0           RETVAL = cs_first_quartile(csample, nelem);
259 0           Safefree(csample);
260             OUTPUT: RETVAL
261              
262              
263             double
264             third_quartile(sample)
265             AV* sample
266             PREINIT:
267             I32 nelem;
268             double* csample;
269             CODE:
270 0           avToCAry(aTHX_ sample, &csample, &nelem);
271 0 0         if (nelem == 0)
272 0           RETVAL = 0.;
273             else
274 0           RETVAL = cs_third_quartile(csample, nelem);
275 0           Safefree(csample);
276             OUTPUT: RETVAL
277              
278              
279             double
280             mean(sample)
281             AV* sample
282             CODE:
283 2           RETVAL = cs_mean_av(aTHX_ sample);
284             OUTPUT: RETVAL
285              
286              
287             double
288             sample_standard_deviation(mean, sample)
289             SV* mean
290             AV* sample
291             CODE:
292 1           RETVAL = cs_sum_deviation_squared_av(aTHX_ SvNV(mean), sample);
293 1 50         RETVAL = pow( RETVAL / av_len(sample), 0.5 ); /* av_len() is N-1! */
294             OUTPUT: RETVAL
295              
296              
297             double
298             population_standard_deviation(mean, sample)
299             SV* mean
300             AV* sample
301             CODE:
302 1           RETVAL = cs_sum_deviation_squared_av(aTHX_ SvNV(mean), sample);
303 1 50         RETVAL = pow( RETVAL / (av_len(sample)+1), 0.5 ); /* av_len() is N-1! */
304             OUTPUT: RETVAL
305              
306              
307             double
308             select_kth(sample, kth)
309             AV* sample
310             I32 kth
311             PREINIT:
312             I32 nelem;
313             double* csample;
314             CODE:
315 17           avToCAry(aTHX_ sample, &csample, &nelem);
316 17 100         if (kth < 1 || kth > nelem) {
    100          
317 3           croak("Can't select %ith smallest element from a list of %i elements", kth, nelem);
318             }
319 14           RETVAL = cs_select(csample, nelem, kth-1);
320 14           Safefree(csample);
321             OUTPUT: RETVAL
322              
323              
324             void
325             median_simple_confidence_limits(sample, confidence, ...)
326             AV* sample
327             double confidence
328             PREINIT:
329             /* "confidence" is 1-alpha */
330             I32 runs, nelem, i_run;
331             double *csample, *destsample, *medians;
332             struct mt* rnd;
333 0           double median = 0.;
334 0           double lower_ci = 0.;
335 0           double upper_ci = 0.;
336             double alpha;
337             INIT:
338 0           alpha = 1.-confidence;
339             PPCODE:
340 0 0         if (items == 2)
341 0           runs = 1000;
342 0 0         else if (items == 3)
343 0           runs = SvUV(ST(2));
344             else {
345 0           croak("Usage: ($lower, $median, $upper) = median_confidence_limits(\\@sample, $confidence, [$nruns]);");
346             }
347 0 0         if (confidence <= 0. || confidence >= 1.) {
    0          
348 0           croak("Confidence level has to be in (0, 1)");
349             }
350 0           rnd = get_rnd(aTHX);
351 0           avToCAry(aTHX_ sample, &csample, &nelem);
352 0 0         if (nelem != 0) {
353 0           median = cs_median(csample, nelem);
354 0           Newx(medians, runs, double);
355 0           Newx(destsample, nelem, double);
356 0 0         for (i_run = 0; i_run < runs; ++i_run) {
357 0           do_resample(csample, nelem, rnd, destsample);
358 0           medians[i_run] = cs_median(destsample, nelem);
359             }
360 0           Safefree(destsample);
361             /* lower = t - (t*_((R+1)*(1-alpha)) - t)
362             * upper = t - (t*_((R+1)*alpha) - t)
363             */
364 0           lower_ci = 2.*median - cs_select( medians, runs, (I32)((runs+1.)*(1.-alpha)) );
365 0           upper_ci = 2.*median - cs_select( medians, runs, (I32)((runs+1.)*alpha) );
366 0           Safefree(medians);
367             }
368 0           Safefree(csample);
369 0 0         EXTEND(SP, 3);
370 0           mPUSHn(lower_ci);
371 0           mPUSHn(median);
372 0           mPUSHn(upper_ci);
373              
374              
375             void
376             simple_confidence_limits_from_samples(statistic, statistics, confidence)
377             double statistic
378             AV* statistics
379             double confidence
380             PREINIT:
381             /* "confidence" is 1-alpha */
382             I32 nelem;
383             double *cstatistics;
384 0           double lower_ci = 0.;
385 0           double upper_ci = 0.;
386             double alpha;
387             INIT:
388 0           alpha = 1.-confidence;
389             PPCODE:
390 0 0         if (confidence <= 0. || confidence >= 1.) {
    0          
391 0           croak("Confidence level has to be in (0, 1)");
392             }
393 0           avToCAry(aTHX_ statistics, &cstatistics, &nelem);
394 0 0         if (nelem != 0) {
395             /* lower = t - (t*_((R+1)*(1-alpha)) - t)
396             * upper = t - (t*_((R+1)*alpha) - t)
397             */
398 0           lower_ci = 2.*statistic - cs_select( cstatistics, nelem, (I32)((nelem+1.)*(1.-alpha)) );
399 0           upper_ci = 2.*statistic - cs_select( cstatistics, nelem, (I32)((nelem+1.)*alpha) );
400             }
401 0           Safefree(cstatistics);
402 0 0         EXTEND(SP, 3);
403 0           mPUSHn(lower_ci);
404 0           mPUSHn(statistic);
405 0           mPUSHn(upper_ci);
406              
407              
408             double
409             approx_erf(x)
410             double x
411             CODE:
412 8           RETVAL = cs_approx_erf(x);
413             OUTPUT: RETVAL
414              
415              
416             double
417             approx_erf_inv(x)
418             double x
419             CODE:
420 7 100         if (x <= 0. || x >= 1.)
    100          
421 4           croak("The inverse error function is defined in (0,1). %f is outside that range", x);
422 3           RETVAL = cs_approx_erf_inv(x);
423             OUTPUT: RETVAL
424              
425              
426             double
427             alpha_to_nsigma(x)
428             double x
429             CODE:
430 3           RETVAL = cs_alpha_to_nsigma(x);
431             OUTPUT: RETVAL
432              
433              
434             double
435             nsigma_to_alpha(x)
436             double x
437             CODE:
438 3           RETVAL = cs_nsigma_to_alpha(x);
439             OUTPUT: RETVAL
440