summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@serenitascapital.com>2015-03-10 14:17:51 -0400
committerGuillaume Horel <guillaume.horel@serenitascapital.com>2015-03-10 14:23:44 -0400
commit544eb106db66e859a0933244bf46624eab1ab555 (patch)
tree12649fe04b627dc0b01b9a30f43fe4260eab2b94
parentc85640622f4686db60f3c6b469e007798f43ad53 (diff)
downloadlossdistrib-544eb106db66e859a0933244bf46624eab1ab555.tar.gz
fix lossdistrib_truncated
-rw-r--r--R/distrib.R8
-rw-r--r--src/lossdistrib.c38
2 files changed, 23 insertions, 23 deletions
diff --git a/R/distrib.R b/R/distrib.R
index 8b10394..277b324 100644
--- a/R/distrib.R
+++ b/R/distrib.R
@@ -294,10 +294,12 @@ lossdistCZ <- function(p, w, S, N, defaultflag=FALSE, rho, Z){
q = matrix(0, N, length(Z)))$q
}
-lossdistC.truncated <- function(p, w, S, N, T=N){
- ## C version of lossdistrib2, roughly 50 times faster
+lossdistC.truncated <- function(p, w, S, N, T=N, defaultflag=FALSE){
+ ## truncated version of lossdistrib
+ ## q[i] is 0 for i>=T
.C("lossdistrib_truncated", as.double(p), as.integer(length(p)),
- as.double(w), as.double(S), as.integer(N), as.integer(T), q = double(T))$q
+ as.double(w), as.double(S), as.integer(N), as.integer(T), as.logical(defaultflag),
+ q = double(N))$q
}
recovdistC <- function(dp, pp, w, S, N){
diff --git a/src/lossdistrib.c b/src/lossdistrib.c
index 61f3c84..d28b1b2 100644
--- a/src/lossdistrib.c
+++ b/src/lossdistrib.c
@@ -145,7 +145,7 @@ void lossdistrib_Z(double *p, int *np, double *w, double *S, int *N, int *defaul
int i, j;
double* pshocked = malloc(sizeof(double) * (*np) * (*nZ));
-#pragma omp parallel for private(j)
+ #pragma omp parallel for private(j)
for(i = 0; i < *nZ; i++){
for(j = 0; j < *np; j++){
pshocked[j + (*np) * i] = shockprob(p[j], rho[j], Z[i], 0);
@@ -172,34 +172,32 @@ void lossdistrib_truncated(double *p, int *np, double *w, double *S, int *N,
int i, j, d1, d2, M;
double lu, d, p1, p2;
- double *q1, *q2;
+ double *qtemp;
+ int one = 1;
+ double pbar;
+ int bound;
lu = 1./(*N-1);
- q1 = calloc( *T, sizeof(double));
- q2 = calloc( *T, sizeof(double));
+ qtemp = malloc( *T * sizeof(double));
q[0] = 1;
M = 1;
for(i=0; i<(*np); i++){
d = (*defaultflag)? w[i] / lu : S[i] * w[i] / lu;
- d1 = floor(d);
- d2 = ceil(d);
- p1 = p[i] * (d2-d);
+ d1 = (int)floor(d);
+ d2 = d1 + 1;
+ p1 = p[i] * ((double)d2-d);
p2 = p[i] - p1;
- for(j=0; j < MIN(M, *T); j++){
- q1[j] = p1 * q[j];
- q2[j] = p2 * q[j];
- q[j] = (1-p[i]) * q[j];
- }
- for(j=0; j < MIN(M, *T-d1); j++){
- q[d1+j] += q1[j];
- };
- for(j=0; j < MIN(M, *T-d2); j++){
- q[d2+j] += q2[j];
- };
+ memcpy(qtemp, q, MIN(M, *T) * sizeof(double));
+ pbar = 1-p[i];
+ bound = MIN(M, *T);
+ dscal_(&bound, &pbar, q, &one);
+ bound = MIN(M, *T-d1);
+ daxpy_(&bound, &p1, qtemp, &one, q+d1, &one);
+ bound = MIN(M, *T-d2);
+ daxpy_(&bound, &p2, qtemp, &one, q+d2, &one);
M += d2;
}
- free(q1);
- free(q2);
+ free(qtemp);
}
void lossdistrib_joint(double *p, int *np, double *w, double *S, int *N, int *defaultflag, double *q) {