Diff of /partyMod/src/Utils.c [000000] .. [fbf06f]

Switch to unified view

a b/partyMod/src/Utils.c
1
2
/**
3
    Some commonly needed utility functions.
4
    *\file Utils.c
5
    *\author $Author$
6
    *\date $Date$
7
*/
8
                
9
#include "party.h"
10
                
11
                
12
/**
13
    Computes the Kronecker product of two matrices\n
14
    *\param A matrix
15
    *\param m nrow(A)
16
    *\param n ncol(A)
17
    *\param B matrix
18
    *\param r nrow(B)
19
    *\param s ncol(B)
20
    *\param ans return value; a pointer to a REALSXP-vector of length (mr x ns)
21
*/
22
23
void C_kronecker (const double *A, const int m, const int n,
24
                  const double *B, const int r, const int s,
25
                  double *ans) {
26
27
    int i, j, k, l, mr, js, ir;
28
    double y;
29
30
    mr = m * r;
31
    for (i = 0; i < m; i++) {
32
        ir = i * r;
33
        for (j = 0; j < n; j++) {
34
            js = j * s;
35
            y = A[j*m + i];
36
            for (k = 0; k < r; k++) {
37
                for (l = 0; l < s; l++) {
38
                    ans[(js + l) * mr + ir + k] = y * B[l * r + k];
39
                }
40
            }
41
        }
42
    }
43
}  
44
45
46
/**
47
    R-interface to C_kronecker
48
    *\param A matrix
49
    *\param B matrix
50
*/
51
                
52
SEXP R_kronecker (SEXP A, SEXP B) {
53
54
    /*  The Kronecker product, a real (mr x ns) matrix */
55
    SEXP ans; 
56
    int *adim, *bdim;
57
58
    if (!isReal(A) || !isReal(B)) 
59
        error("R_kronecker: A and B are not of type REALSXP");
60
61
    if (isMatrix(A)) {
62
        adim = INTEGER(getAttrib(A, R_DimSymbol));
63
    } else {
64
        /* assume row vectors */
65
        adim = Calloc(2, int);
66
        adim[0] = 1;
67
        adim[1] = LENGTH(A);
68
    }
69
    
70
    if (isMatrix(B)) {
71
        bdim = INTEGER(getAttrib(B, R_DimSymbol));
72
    } else {
73
        /* assume row vectors */
74
        bdim = Calloc(2, int);
75
        bdim[0] = 1;
76
        bdim[1] = LENGTH(B);
77
    }
78
79
    PROTECT(ans = allocMatrix(REALSXP, 
80
                              adim[0] * bdim[0], 
81
                              adim[1] * bdim[1]));
82
    C_kronecker(REAL(A), adim[0], adim[1], 
83
                REAL(B), bdim[0], bdim[1], REAL(ans));
84
    if (!isMatrix(A)) Free(adim); 
85
    if (!isMatrix(B)) Free(bdim);
86
    UNPROTECT(1);
87
    return(ans);
88
}
89
90
91
/**
92
    C- and R-interface to La_svd 
93
    *\param jobu
94
    *\param jobv
95
    *\param x
96
    *\param s
97
    *\param u
98
    *\param v
99
    *\param method
100
*/
101
102
void CR_La_svd(int dim, SEXP jobu, SEXP jobv, SEXP x, SEXP s, SEXP u, SEXP v,
103
               SEXP method)
104
{
105
    int *xdims, n, p, lwork, info = 0;
106
    int *iwork;
107
    double *work, *xvals, tmp;
108
    /* const char * meth; not used*/
109
110
    if (!(isString(jobu) && isString(jobv)))
111
    error(("'jobu' and 'jobv' must be character strings"));
112
    if (!isString(method))
113
    error(("'method' must be a character string"));
114
    /* meth = CHAR(STRING_ELT(method, 0)); not used */
115
    xdims = INTEGER(coerceVector(getAttrib(x, R_DimSymbol), INTSXP));
116
    n = xdims[0]; p = xdims[1];
117
    xvals = Calloc(n * p, double);
118
    /* work on a copy of x */
119
    Memcpy(xvals, REAL(x), (size_t) (n * p));
120
121
    {
122
    int ldu = INTEGER(getAttrib(u, R_DimSymbol))[0],
123
        ldvt = INTEGER(getAttrib(v, R_DimSymbol))[0];
124
        /* this only works for SQUARE matrices, potentially
125
           with reduced dimension, so use dim x dim for input and
126
           output */
127
        ldu = dim;
128
        ldvt = dim;
129
    iwork= (int *) Calloc(8*(n<p ? n : p), int);
130
131
    /* ask for optimal size of work array */
132
    lwork = -1;
133
    F77_CALL(dgesdd)(CHAR(STRING_ELT(jobu, 0)),
134
/* was           &n, &p, xvals, &n, REAL(s), for the non-square case */
135
             &dim, &dim, xvals, &dim, REAL(s),
136
             REAL(u), &ldu,
137
             REAL(v), &ldvt,
138
             &tmp, &lwork, iwork, &info);
139
    if (info != 0)
140
        error(("error code %d from Lapack routine '%s'"), info, "dgesdd");
141
    lwork = (int) tmp;
142
    work = Calloc(lwork, double);
143
    F77_CALL(dgesdd)(CHAR(STRING_ELT(jobu, 0)),
144
             &dim, &dim, xvals, &dim, REAL(s),
145
/* was           &n, &p, xvals, &n, REAL(s), for the non-square case */
146
             REAL(u), &ldu,
147
             REAL(v), &ldvt,
148
             work, &lwork, iwork, &info);
149
    if (info != 0)
150
        error(("error code %d from Lapack routine '%s'"), info, "dgesdd");
151
    }
152
    Free(work); Free(xvals); Free(iwork);
153
}
154
155
/**
156
    C-interface to CR_La_svd
157
    *\param x matrix
158
    *\param svdmem an object of class `svd_mem'
159
*/
160
161
void C_svd (SEXP x, SEXP svdmem) {
162
163
    int p, i;
164
    double *du, *dv;
165
166
    if (!isMatrix(x) || !isReal(x))
167
        error("x is not a real matrix");
168
169
    du = REAL(GET_SLOT(svdmem, PL2_uSym));
170
    dv = REAL(GET_SLOT(svdmem, PL2_vSym));
171
    p = INTEGER(GET_SLOT(svdmem, PL2_pSym))[0];
172
    if (nrow(x) < p) error("svd p x error");
173
    for (i = 0; i < p*p; i++) {
174
        du[i] = 0.0;
175
        dv[i] = 0.0;
176
    }
177
    CR_La_svd(p, GET_SLOT(svdmem, PL2_jobuSym), 
178
        GET_SLOT(svdmem, PL2_jobvSym), x, GET_SLOT(svdmem, PL2_sSym), 
179
        GET_SLOT(svdmem, PL2_uSym), GET_SLOT(svdmem, PL2_vSym), 
180
        GET_SLOT(svdmem, PL2_methodSym));
181
    /* return(R_NilValue); */
182
}
183
184
185
/**
186
    R-interface to CR_La_svd
187
    *\param x matrix
188
    *\param svdmem an object of class `svd_mem'
189
*/
190
191
SEXP R_svd (SEXP x, SEXP svdmem) {
192
193
    C_svd(x, svdmem);
194
    return(R_NilValue);
195
}
196
197
198
/**
199
    Reorder the linear statistic, expectation, and covariance
200
    in a way that elements with zero variance come last. These
201
    will be ignored in later computation of the MP inverse
202
    *\param x an object of class `LinStatExpectCovarMPinv'
203
*/
204
205
void C_linexpcovReduce (SEXP x) {
206
207
    double *dlinstat, *dexp, *dcov;
208
    double *dlinstat2, *dexp2, *dcov2;
209
    int pq, pqn, *zerovar, i, j, itmp, jtmp, sumzv = 0, *dim;
210
211
    /* the statistic, expectation, covariance in original dimension */    
212
    pq = INTEGER(GET_SLOT(x, PL2_dimensionSym))[0];
213
    dlinstat = REAL(GET_SLOT(x, PL2_linearstatisticSym));
214
    dexp = REAL(GET_SLOT(x, PL2_expectationSym));
215
    dcov = REAL(GET_SLOT(x, PL2_covarianceSym));
216
217
    /* indicator of zero variance */
218
    zerovar = Calloc(pq, int);
219
220
    /* identify and count zero variances (we can use 0.0 because variances
221
       corresponding to empty levels are exactly zero */
222
    for (i = 0; i < pq; i++) {
223
        if (dcov[i + i * pq] > 0.0) {
224
            zerovar[i] = 0;
225
        } else {
226
            zerovar[i] = 1;
227
            sumzv++;
228
        }
229
    }
230
231
    /* if there is any such element and not all variances are zero*/
232
    if ((sumzv > 0) & (sumzv < pq)) {
233
234
        /* do we really need a copy ? */
235
        pqn = pq - sumzv;
236
        dlinstat2 = Calloc(pq, double);
237
        dexp2 = Calloc(pq, double);
238
        dcov2 = Calloc(pq * pq, double);
239
        
240
        /* init */
241
        for (i = 0; i < pq; i++) {
242
            dlinstat2[i] = 0.0; 
243
            dexp2[i] = 0.0; 
244
            for (j = 0; j < pq; j++)
245
                dcov2[i + j*pq] = 0.0;
246
        }
247
        
248
        /* overwrite zero variance elements with subsequent elements */
249
        itmp = 0;
250
        for (i = 0; i < pq; i++) {
251
            if (zerovar[i] == 0) {
252
                dlinstat2[itmp] = dlinstat[i];
253
                dexp2[itmp] = dexp[i];
254
                jtmp = 0;
255
                for (j = 0; j < pq; j++) {
256
                    if (zerovar[j] == 0) {
257
                        dcov2[itmp + jtmp * pqn] = dcov[i + j * pq];
258
                        jtmp++;
259
                    }
260
                }
261
                itmp++;
262
            }
263
        }
264
                                        
265
        for (i = 0; i < pq; i++) {
266
            dlinstat[i] = dlinstat2[i]; 
267
            dexp[i] = dexp2[i]; 
268
            for (j = 0; j < pq; j++)
269
                dcov[i + j*pq] = dcov2[i + j * pq];
270
        }
271
272
        /* ATTENTION: This is dangerous but the only way to tell
273
           svd and friends that we want to use the first pqn elements only! */
274
        dim = INTEGER(GET_SLOT(x, PL2_dimensionSym));
275
        dim[0] = pqn;
276
        /* we reset the original dimension in C_TestStatistic */
277
        
278
        Free(dlinstat2);
279
        Free(dexp2);
280
        Free(dcov2);
281
    }
282
    Free(zerovar);
283
}
284
285
286
/**
287
    R-interface to C_linexpcovReduce
288
    *\param x an object of class `LinStatExpectCovarMPinv'
289
*/
290
291
SEXP R_linexpcovReduce (SEXP x) {
292
293
    C_linexpcovReduce(x);
294
    return(R_NilValue);
295
}
296
        
297
298
/**
299
    Moore-Penrose inverse of a matrix
300
    *\param x matrix
301
    *\param tol a tolerance bound
302
    *\param svdmem an object of class `svd_mem'
303
    *\param ans return value; an object of class `ExpectCovarMPinv'
304
*/
305
306
void C_MPinv (SEXP x, double tol, SEXP svdmem, SEXP ans) {
307
308
    SEXP d, u, vt;
309
    int i, j, p, pn, k, *positive;
310
    double *dd, *du, *dvt, *dMPinv;
311
    double *drank;
312
    
313
    drank = REAL(GET_SLOT(ans, PL2_rankSym));
314
    dMPinv = REAL(GET_SLOT(ans, PL2_MPinvSym));
315
316
    C_svd(x, svdmem);
317
    d = GET_SLOT(svdmem, PL2_sSym);
318
    dd = REAL(d);
319
    u = GET_SLOT(svdmem, PL2_uSym);
320
    du = REAL(u);
321
    vt = GET_SLOT(svdmem, PL2_vSym);
322
    dvt = REAL(vt);
323
    /* this may be the reduced dimension! Use the first p elements only!!!*/
324
    p = INTEGER(GET_SLOT(svdmem, PL2_pSym))[0];
325
326
    if (tol * dd[0] > tol) tol = tol * dd[0];
327
328
    positive = Calloc(p, int); 
329
    
330
    drank[0] = 0.0;
331
    for (i = 0; i < p; i++) {
332
        if (dd[i] > tol) {
333
            positive[i] = 1;
334
            drank[0] += 1.0;
335
        } 
336
    }
337
    
338
    for (j = 0; j < p; j++) {
339
        if (positive[j]) {
340
            for (i = 0; i < p; i++)
341
                du[j * p + i] *= (1 / dd[j]);
342
        }
343
    }
344
    
345
    for (i = 0; i < p; i++) {
346
        for (j = 0; j < p; j++) {
347
            dMPinv[j * p + i] = 0.0;
348
            for (k = 0; k < p; k++) {
349
                if (positive[k])
350
                    dMPinv[j * p + i] += dvt[i * p + k] * du[p * k + j];
351
            }
352
        }
353
    }
354
355
    Free(positive);
356
}
357
358
359
/**
360
    R-interface to C_MPinv 
361
    *\param x matrix
362
    *\param tol a tolerance bound
363
    *\param svdmem an object of class `svd_mem'
364
*/
365
366
SEXP R_MPinv (SEXP x, SEXP tol, SEXP svdmem) {
367
368
    SEXP ans;
369
    int p;
370
371
    if (!isMatrix(x) || !isReal(x))
372
        error("R_MPinv: x is not a real matrix");
373
374
    if (nrow(x) != ncol(x)) 
375
        error("R_MPinv: x is not a square matrix");
376
377
    if (!isReal(tol) || LENGTH(tol) != 1)
378
        error("R_MPinv: tol is not a scalar real");
379
380
    p = nrow(x);
381
    /* potentially, the effective dimension was reduced
382
    if (p != INTEGER(GET_SLOT(svdmem, PL2_pSym))[0])
383
        error("R_MPinv: dimensions don't match");
384
    */
385
386
    PROTECT(ans = NEW_OBJECT(MAKE_CLASS("LinStatExpectCovarMPinv")));
387
    SET_SLOT(ans, PL2_MPinvSym, PROTECT(allocMatrix(REALSXP, p, p)));
388
    SET_SLOT(ans, PL2_rankSym, PROTECT(allocVector(REALSXP, 1)));
389
    
390
    C_MPinv(x, REAL(tol)[0], svdmem, ans);
391
    
392
    UNPROTECT(3);
393
    return(ans);
394
}
395
396
397
/**
398
    the maximum of a double vector
399
    *\param x vector
400
    *\param n its length
401
*/
402
403
404
double C_max(const double *x, const int n) {
405
   double tmp = 0.0;
406
   int i;
407
   
408
   for (i = 0; i < n; i++) {
409
       if (x[i] > tmp) tmp = x[i];
410
   }
411
   return(tmp);
412
}
413
414
415
/**
416
    R-interface to C_max
417
    *\param x numeric vector
418
*/
419
420
SEXP R_max(SEXP x) {
421
422
    SEXP ans;
423
    int n;
424
    
425
    if (!isReal(x)) 
426
        error("R_max: x is not of type REALSXP");
427
    n = LENGTH(x);
428
    PROTECT(ans = allocVector(REALSXP, 1));
429
    REAL(ans)[0] = C_max(REAL(x), n);
430
    UNPROTECT(1);
431
    return(ans);
432
}
433
434
435
/**
436
    absolute value 
437
    *\param x numeric vector
438
    *\param n length(x)
439
*/
440
441
void C_abs(double *x, int n) {
442
443
    int i;
444
    for (i = 0; i < n; i++) x[i] = fabs(x[i]);
445
}
446
447
448
/**
449
    R-interface to C_abs
450
    *\param x numeric vector
451
*/
452
453
SEXP R_abs(SEXP x) {
454
455
    SEXP ans;
456
    int n;
457
    
458
    if (!isReal(x)) 
459
        error("R_max: x is not of type REALSXP");
460
    n = LENGTH(x);
461
    PROTECT(ans = duplicate(x));
462
    C_abs(REAL(ans), n);
463
    UNPROTECT(1);
464
    return(ans);
465
}
466
467
468
/**
469
    matrix product x %*% y
470
    *\param x a matrix
471
    *\param nrx number of rows of x
472
    *\param ncx number of cols of x
473
    *\param y a matrix
474
    *\param nry number of rows of y
475
    *\param ncy number of cols of y
476
    *\param z a matrix of dimension nrx x ncy
477
*/
478
479
void C_matprod(double *x, int nrx, int ncx,
480
               double *y, int nry, int ncy, double *z)
481
{
482
    const char *transa = "N", *transb = "N";
483
    double one = 1.0, zero = 0.0;
484
    int i;
485
486
    if (nrx > 0 && ncx > 0 && nry > 0 && ncy > 0) {
487
        F77_CALL(dgemm)(transa, transb, &nrx, &ncy, &ncx, &one,
488
                    x, &nrx, y, &nry, &zero, z, &nrx);
489
    } else /* zero-extent operations should return zeroes */
490
    for(i = 0; i < nrx*ncy; i++) z[i] = 0;
491
}
492
493
494
/**
495
    R-interface to C_matprod
496
    *\param x a matrix
497
    *\param y a matrix
498
*/
499
500
SEXP R_matprod(SEXP x, SEXP y) {
501
502
    SEXP ans;
503
    
504
    int nrx, ncx, nry, ncy;
505
    
506
    nrx = nrow(x);
507
    ncx = ncol(x);
508
    nry = nrow(y);
509
    ncy = ncol(y);
510
511
    if (ncx != nry)
512
        error("R_matprod: dimensions don't match");
513
    PROTECT(ans = allocMatrix(REALSXP, nrx, ncy));
514
    C_matprod(REAL(x), nrx, ncx, REAL(y), nry, ncy, REAL(ans));
515
    UNPROTECT(1);
516
    return(ans);
517
}
518
519
520
/**
521
    matrix product x %*% t(y)
522
    *\param x a matrix
523
    *\param nrx number of rows of x
524
    *\param ncx number of cols of x
525
    *\param y a matrix
526
    *\param nry number of rows of y
527
    *\param ncy number of cols of y
528
    *\param z a matrix of dimension nrx x ncy
529
*/
530
531
void C_matprodT(double *x, int nrx, int ncx,
532
                double *y, int nry, int ncy, double *z)
533
{
534
    const char *transa = "N", *transb = "T";
535
    double one = 1.0, zero = 0.0;
536
    int i;
537
538
    if (nrx > 0 && ncx > 0 && nry > 0 && ncy > 0) {
539
        F77_CALL(dgemm)(transa, transb, &nrx, &nry, &ncy, &one,
540
                    x, &nrx, y, &nry, &zero, z, &nrx);
541
    } else /* zero-extent operations should return zeroes */
542
    for(i = 0; i < nrx*nry; i++) z[i] = 0;
543
}
544
545
546
/**
547
    R-interface to C_matprodT
548
    *\param x a matrix
549
    *\param y a matrix
550
*/
551
552
SEXP R_matprodT(SEXP x, SEXP y) {
553
554
    SEXP ans;
555
    int nrx, ncx, nry, ncy;
556
    
557
    nrx = nrow(x);
558
    ncx = ncol(x);
559
    nry = nrow(y);
560
    ncy = ncol(y);
561
562
    if (ncx != ncy)
563
        error("R_matprod: dimensions don't match");
564
    PROTECT(ans = allocMatrix(REALSXP, nrx, nry));
565
    C_matprodT(REAL(x), nrx, ncx, REAL(y), nry, ncy, REAL(ans));
566
    UNPROTECT(1);
567
    return(ans);
568
}
569
570
571
/**
572
    compute a permutation of a (random subset of) 0:(m-1)
573
    *\param x an integer vector of length m
574
    *\param m integer
575
    *\param k integer
576
    *\param ans an integer vector of length k
577
*/    
578
579
void C_SampleNoReplace(int *x, int m, int k, int *ans) {
580
     
581
    int i, j, n = m;
582
583
    for (i = 0; i < m; i++)
584
        x[i] = i;
585
    for (i = 0; i < k; i++) {
586
        j = floor((double) n * unif_rand()); 
587
        ans[i] = x[j];
588
        x[j] = x[--n];  
589
    }
590
}
591
592
593
/**
594
    R-interface to C_SampleNoReplace: the permutation case
595
    *\param m integer
596
*/    
597
598
SEXP R_permute(SEXP m) {
599
    
600
    SEXP x, ans;
601
    int n;
602
    
603
    n = INTEGER(m)[0];
604
    PROTECT(x = allocVector(INTSXP, n));
605
    PROTECT(ans = allocVector(INTSXP, n));
606
    C_SampleNoReplace(INTEGER(x), n, n, INTEGER(ans));
607
    UNPROTECT(2);
608
    return(ans);
609
}
610
611
612
/**
613
    R-interface to C_SampleNoReplace: the subset case
614
    *\param m integer
615
    *\param k integer
616
*/    
617
618
SEXP R_rsubset(SEXP m, SEXP k) {
619
    
620
    SEXP x, ans;
621
    int n, j;
622
    
623
    n = INTEGER(m)[0];
624
    j = INTEGER(k)[0];
625
    PROTECT(x = allocVector(INTSXP, n));
626
    PROTECT(ans = allocVector(INTSXP, j));
627
    C_SampleNoReplace(INTEGER(x), n, j, INTEGER(ans));
628
    UNPROTECT(2);
629
    return(ans);
630
}
631
632
/* Unequal probability sampling; without-replacement case */
633
634
void C_ProbSampleNoReplace(int n, double *p, int *perm,
635
                           int nans, int *ans)
636
{
637
    double rT, mass, totalmass;
638
    int i, j, k, n1;
639
640
    /* Record element identities */
641
    for (i = 0; i < n; i++)
642
    perm[i] = i + 1;
643
644
    /* Sort probabilities into descending order */
645
    /* Order element identities in parallel */
646
    revsort(p, perm, n);
647
648
    /* Compute the sample */
649
    totalmass = 1;
650
    for (i = 0, n1 = n-1; i < nans; i++, n1--) {
651
    rT = totalmass * unif_rand();
652
    mass = 0;
653
    for (j = 0; j < n1; j++) {
654
        mass += p[j];
655
        if (rT <= mass)
656
        break;
657
    }
658
    ans[i] = perm[j];
659
    totalmass -= p[j];
660
    for(k = j; k < n1; k++) {
661
        p[k] = p[k + 1];
662
        perm[k] = perm[k + 1];
663
    }
664
    }
665
}
666
667
668
/**
669
    determine if i is element of the integer vector set
670
    *\param i an integer
671
    *\param iset a pointer to an integer vector
672
    *\param p length(iset)
673
*/
674
675
int i_in_set(int i, int *iset, int p) {
676
677
    int j, is = 0;
678
        
679
    if (p == 0) return(0);
680
                    
681
    for (j = 0; j < p; j++) {
682
        if (iset[j] == i) {  
683
            is = 1;
684
            break; 
685
        }
686
    }
687
    return(is);
688
}
689
690
int C_i_in_set(int i, SEXP set) {
691
    if (LENGTH(set) > 0)
692
        return(i_in_set(i, INTEGER(set), LENGTH(set)));
693
    else 
694
        return(0);
695
}
696
    
697
int nrow(SEXP x) {
698
    return(INTEGER(getAttrib(x, R_DimSymbol))[0]);
699
}
700
701
int ncol(SEXP x) {
702
    return(INTEGER(getAttrib(x, R_DimSymbol))[1]);
703
}
704
705
/* compute index of variable with smallest p-value 
706
   (and largest test statistic in case two or more p-values coincide -- 
707
    should not happen anymore since we use 1 - (1 - p)^k for Bonferroni adjustment)
708
*/
709
int C_whichmax(double *pvalue, double *teststat, int ninputs) {
710
711
    int ans = -1, j;
712
    double tmppval = 0.0, tmptstat = 0.0;
713
       
714
    /* <FIXME> can we switch to the log scale here? </FIXME> */
715
716
    tmppval = 0.0;
717
    tmptstat = 0.0;
718
    for (j = 0; j < ninputs; j++) {
719
        if (pvalue[j] > tmppval) {
720
            ans = j;
721
            tmppval = pvalue[j];
722
            tmptstat = teststat[j];
723
        } else {
724
            if (pvalue[j] == tmppval && teststat[j] > tmptstat) {  
725
                ans = j;
726
                tmppval = pvalue[j];
727
                tmptstat = teststat[j];
728
            }
729
        }
730
    }
731
    return(ans);
732
}
733
734
SEXP R_whichmax(SEXP x, SEXP y) {
735
    SEXP ans;
736
    
737
    if (LENGTH(x) != LENGTH(y)) error("different length");
738
    PROTECT(ans = allocVector(INTSXP, 1));
739
    INTEGER(ans)[0] = C_whichmax(REAL(x), REAL(y), LENGTH(x));
740
    UNPROTECT(1);
741
    return(ans);
742
}
743
744
SEXP R_listplus(SEXP a, SEXP b, SEXP which) {
745
746
    int na, nb, i, j, *iwhich;
747
    double *dae, *dbe;
748
    SEXP ae, be;
749
750
    na = LENGTH(a);
751
    nb = LENGTH(b);
752
    if (na != nb) error("a and b are of different length");
753
    
754
    iwhich = LOGICAL(which);
755
    
756
    for (i = 0; i < na; i++) {
757
        if (iwhich[i]) continue;
758
        
759
        ae = VECTOR_ELT(a, i);
760
        be = VECTOR_ELT(b, i);
761
762
        if (LENGTH(ae) != LENGTH(be)) 
763
            error("elements %d are of different length", i);
764
            
765
        if (!isReal(ae) || !isReal(be))
766
            error("elements %d are not of type double", i);
767
            
768
        dae = REAL(ae);
769
        dbe = REAL(be);
770
        for (j = 0; j < LENGTH(ae); j++) 
771
            dae[j] += dbe[j];
772
    }
773
    return(a);
774
}
775
776
SEXP R_modify_response(SEXP x, SEXP vf) {
777
778
    double *src, *tar;
779
    int i, n;
780
    
781
    src = REAL(x);
782
    n = LENGTH(x);
783
784
    tar = REAL(get_transformation(vf, 1));
785
    for (i = 0; i < n; i++)
786
        tar[i] = src[i];
787
788
    tar = REAL(get_test_trafo(vf));
789
    for (i = 0; i < n; i++)
790
        tar[i] = src[i];
791
792
    tar = REAL(get_predict_trafo(vf));
793
    for (i = 0; i < n; i++)
794
        tar[i] = src[i];
795
796
    tar = REAL(get_variable(vf, 1));
797
    for (i = 0; i < n; i++)
798
        tar[i] = src[i];
799
                                          
800
    return(R_NilValue);
801
}
802
803
double F77_SUB(unifrnd)(void) { return unif_rand(); }
804
805
void C_SampleSplitting(int n, double *prob, int *weights, int k) {
806
807
    int i;
808
    double *tmpprob;
809
    int *ans, *perm;
810
811
    tmpprob = Calloc(n, double);
812
    perm = Calloc(n, int);
813
    ans = Calloc(k, int);
814
    for (i = 0; i < n; i++) tmpprob[i] = prob[i];
815
816
    C_ProbSampleNoReplace(n, tmpprob, perm, k, ans);
817
    for (i = 0; i < n; i++) weights[i] = 0;
818
    for (i = 0; i < k; i++)
819
        weights[ans[i] - 1] = 1;
820
    Free(tmpprob); Free(perm); Free(ans);
821
}
822
823
/**
824
    Remove weights vector from each node of a tree (in order to save memory)
825
    \*param subtree a tree
826
*/ 
827
828
void C_remove_weights(SEXP subtree, int removestats) {
829
830
    SET_VECTOR_ELT(subtree, S3_WEIGHTS, R_NilValue);
831
    
832
    if (!S3get_nodeterminal(subtree)) {
833
        if (removestats) {
834
            SET_VECTOR_ELT(VECTOR_ELT(subtree, S3_CRITERION), 
835
                           S3_iCRITERION, R_NilValue);
836
            SET_VECTOR_ELT(VECTOR_ELT(subtree, S3_CRITERION), 
837
                           S3_STATISTICS, R_NilValue);
838
        }
839
        C_remove_weights(S3get_leftnode(subtree), removestats);
840
        C_remove_weights(S3get_rightnode(subtree), removestats);
841
    }
842
}
843
844
SEXP R_remove_weights(SEXP subtree, SEXP removestats) {
845
846
    C_remove_weights(subtree, LOGICAL(removestats)[0]);
847
    return(R_NilValue);
848
}
849
850
double* C_tempweights(int j, SEXP weights, SEXP fitmem, SEXP inputs) {
851
852
    int nobs, *iNAs, i, k;
853
    double *dw, *dweights;
854
    SEXP NAs;
855
    
856
    dw = REAL(get_weights(fitmem));
857
    nobs = LENGTH(weights);
858
    dweights = REAL(weights);
859
    NAs = get_missings(inputs, j);
860
    iNAs = INTEGER(NAs);
861
    if (length(NAs) == 0) return(dw);
862
    for (i = 0; i < nobs; i++) dw[i] = dweights[i];
863
    for (k = 0; k < LENGTH(NAs); k++)
864
        dw[iNAs[k] - 1] = 0.0;
865
    
866
    return(dw);
867
}