If-Statements and integrate() function in R - r

Do if statements not work for integrate? I have to do something much more complicated than this, but I am supplying this example because it isolated the problem.
Kernel = function(x){
if(abs(x)<1){
w = 1 - abs(x)
} else{
w = 0
}
return(w)
}
integrate(Kernel,
0,
1)
The error message:
the condition has length > 1 and only the first element will be used

Kernel = function(x){
pmax(1-abs(x), 0)
}
integrate(Kernel, 0, 1)
0.5 with absolute error < 5.6e-15
or even:
Kernel1 = function(x){
ifelse(abs(x)<1, 1-abs(x), 0)
}
integrate(Kernel1, 0, 1)
0.5 with absolute error < 5.6e-15
If you want to maintain the way you have written your function, you have to vectorize it:
Kernel2 = function(x){
ifelse(abs(x)< 1, 1-abs(x), 0)
if(abs(x)<1){
w = 1 - abs(x)
} else{
w = 0
}
return(w)
}
integrate(Vectorize(Kernel2), 0, 1)
0.5 with absolute error < 5.6e-15

Related

Getting node stack overflow error in R for Quicksort

quicksort <- function(x, s, e) {
p = s
i = 0
j = 0
for (k in 1:length(x)) {
if (x[p] < x[k])
i = k
}
if (!i)
i = e
for (k in length(x):1) {
if (x[p] > x[k])
j = k
}
if (!j)
j = s
if (i < j) {
t = x[i]
x[i] = x[j]
x[j] = t
} else {
t = x[j]
x[j] = x[p]
x[p] = t
quicksort(x, s, j - 1)
quicksort(x, j + 1, e)
}
x
}
quick = function(x) {
quicksort(x, 1, length(x))
}
When I run this i R console with a Vector I getting Error
> x<-c(4,47,480,15,0,147,1,56862,12)
> quick(x)
Error: node stack overflow
Its working when testing each command in R console but complete code doesn't work perfectly is the logic correct or wrong with code
Modified the Code as
quicksort<-function(x){
if(length(x)<=1)return(x)
p<-x[1]
therest<-x[-1]
i<-therest[therest<p]
j<-therest[therest>p]
i<-quicksort(i)
j<-quicksort(j)
return(c(i,p,j))
}
Now it Works The Console is responded as
> x<-c(4,47,480,15,0,147,1,56862,12)
> quicksort(x)
[1] 0 1 4 12 15 47 147 480 56862
The Code in the Question is implementation from C++ but code there in the answer is direct R

implement matrix determinant in R

I was asked to implement function that calculates n-dimensional matrix determinant using Laplace expansion. This involves recursion. I developed this:
minor<-function(A,i,j) {
return(A[c(1:(i-1),(i+1):dim(A)[1]),c(1:(j-1),(j+1):dim(A)[2])])
}
determinantRec<-function(X,k) {
if (dim(X)[1] == 1 && dim(X)[2] == 1) return(X[1][1])
else {
s = 0
for (i in 1:dim(X)[2]) {
s = s + X[k][i]*(-1)^(k+i)*determinantRec(minor(X,k,i),k)
}
return(s)
}
}
where k in determinantRec(X,k) function indicates which row I want to use Laplace expansion along of.
My problem is when I run determinantRec(matrix(c(1,2,3,4),nrow = 2,ncol = 2),1) this error appears:
C stack usage 7970628 is too close to the limit
What is wrong with my code?
#julia, there is one simple type in your code. Just remove the '*' at the end of the definition of 's'. And don't indent the recursion.
determinantRek<-function(X,k) {
if (dim(X)[1] == 1 && dim(X)[2] == 1)
return(X[1,1])
if (dim(X)[1] == 2 && dim(X)[2] == 2)
return(X[1,1]*X[2,2]-X[1,2]*X[2,1])
else
s = 0
for (i in 1:dim(X)[2]) {
s = s + X[k,i]*(-1)^(k+i)
determinantRek(X[-k,-i],k)
}
return(s)
}
I did this way and works just fine, although it is super slow, compared to the det function in base R
laplace_expansion <- function(mat){
det1 <- function(mat){
mat[1]*mat[4]-mat[2]*mat[3]
}
determinant <- 0
for(j in 1:ncol(mat)){
mat1 <- mat[-1,-j]
if(nrow(mat1) == 2){
determinant <- determinant+mat[1,j]*(-1)^(1+j)*det1(mat1)
}else{
val <- mat[1,j]*(-1)^(1+j)
if(val != 0){
determinant <- determinant+val*laplace_expansion(mat1)
}
}
}
return(determinant)
}
This is my approach, I think it's cleaner.
deter <- function(X) {
stopifnot(is.matrix(X))
stopifnot(identical(ncol(X), nrow(X)))
if (all(dim(X) == c(1, 1))) return(as.numeric(X))
i <- 1:nrow(X)
out <- purrr::map_dbl(i, function(i){
X[i, 1] * (-1)^(i + 1) * deter(X[-i, -1, drop = FALSE])
})
return(sum(out))
}
Thank you #ArtemSokolov and #MrFlick for pointing the problem cause, it was it. I also discovered that this code does not calculate properly the determinant of 2x2 matrix. After all it looks like that:
determinantRek<-function(X,k) {
if (dim(X)[1] == 1 && dim(X)[2] == 1)
return(X[1,1])
if (dim(X)[1] == 2 && dim(X)[2] == 2)
return(X[1,1]*X[2,2]-X[1,2]*X[2,1])
else
s = 0
for (i in 1:dim(X)[2]) {
s = s + X[k,i]*(-1)^(k+i)*
determinantRek(X[-k,-i],k)
}
return(s)
}
Debuging with browser() was also helpful :)

R function wrapper than maintains function signature

I am trying to write a very simple function wrapper in R, that will accept f and return g where g returns zero whenever the first argument is negative. I have the following code
wrapper <- function(f) {
function(x, ...) {
if( x <= 0 ) { 0 }
else { f(x, ...) }
}
}
Thge wrapper works as expected, but is there are way to maintain the function signature
> wdnorm <- wrapper(dnorm)
> args(dnorm)
function (x, mean = 0, sd = 1, log = FALSE)
NULL
> args(wdnorm)
function (x, ...)
NULL
I would like to do something like this (but obviously it doesn't work)
args(g) <- args(f)
is this possible in R?
Here is what you want. Tho, do you really need this?
wrapper <- function(f) {
f2 = function(x) {
if (x <= 0) { 0 }
else { do.call(f, as.list( match.call())[-1]) }
}
formals(f2) = formals(f)
f2
}
wdnorm <- wrapper(dnorm)
args(dnorm)
args(wdnorm)
wdnorm(-5)
wdnorm(5)
output
> args(dnorm)
function (x, mean = 0, sd = 1, log = FALSE)
NULL
> args(wdnorm)
function (x, mean = 0, sd = 1, log = FALSE)
NULL
> wdnorm(-5)
[1] 0
> wdnorm(5)
[1] 1.48672e-06

canberra distance - inconsistent results

I'm trying to understand what's going on with my calculation of canberra distance. I write my own simple canberra.distance function, however the results are not consistent with dist function. I added option na.rm = T to my function, to be able calculate the sum when there is zero denominator. From ?dist I understand that they use similar approach: Terms with zero numerator and denominator are omitted from the sum and treated as if the values were missing.
canberra.distance <- function(a, b){
sum( (abs(a - b)) / (abs(a) + abs(b)), na.rm = T )
}
a <- c(0, 1, 0, 0, 1)
b <- c(1, 0, 1, 0, 1)
canberra.distance(a, b)
> 3
# the result that I expected
dist(rbind(a, b), method = "canberra")
> 3.75
a <- c(0, 1, 0, 0)
b <- c(1, 0, 1, 0)
canberra.distance(a, b)
> 3
# the result that I expected
dist(rbind(a, b), method = "canberra")
> 4
a <- c(0, 1, 0)
b <- c(1, 0, 1)
canberra.distance(a, b)
> 3
dist(rbind(a, b), method = "canberra")
> 3
# now the results are the same
Pairs 0-0 and 1-1 seem to be problematic. In the first case (0-0) both numerator and denominator are equal to zero and this pair should be omitted. In the second case (1-1) numerator is 0 but denominator is not and the term is then also 0 and the sum should not change.
What am I missing here?
EDIT:
To be in line with R definition, function canberra.distance can be modified as follows:
canberra.distance <- function(a, b){
sum( abs(a - b) / abs(a + b), na.rm = T )
}
However, the results are the same as before.
This might shed some light on the difference. As far as I can see this is the actual code being run for computing the distance
static double R_canberra(double *x, int nr, int nc, int i1, int i2)
{
double dev, dist, sum, diff;
int count, j;
count = 0;
dist = 0;
for(j = 0 ; j < nc ; j++) {
if(both_non_NA(x[i1], x[i2])) {
sum = fabs(x[i1] + x[i2]);
diff = fabs(x[i1] - x[i2]);
if (sum > DBL_MIN || diff > DBL_MIN) {
dev = diff/sum;
if(!ISNAN(dev) ||
(!R_FINITE(diff) && diff == sum &&
/* use Inf = lim x -> oo */ (int) (dev = 1.))) {
dist += dev;
count++;
}
}
}
i1 += nr;
i2 += nr;
}
if(count == 0) return NA_REAL;
if(count != nc) dist /= ((double)count/nc);
return dist;
}
I think the culprit is this line
if(!ISNAN(dev) ||
(!R_FINITE(diff) && diff == sum &&
/* use Inf = lim x -> oo */ (int) (dev = 1.)))
which handles a special case and may not be documented.

Error .. missing value where TRUE/FALSE needed

I have been trying to run this code (below here) and I have gotten that message "Error in if (temp[ii] == 0) { : missing value where TRUE/FALSE needed"...
temp = c(2.15, 3.5, 0, 0, 0, 1.24, 5.42, 6.87)
tm = length(temp)
for (i in 1:tm){
if (temp[i] == 0) {
counter3 = 1
last = temp[i - 1]
for (ii in i + 1:tm){
if (temp[ii] == 0) {
counter3 = counter3 + 1
}
if (temp[ii] != 0) {
nxt = temp[i + counter3]
}
}
}
}
Your problem is that temp[ii] is returning NA because ii goes out of bounds:
ii = i + 1:tm #Your declaration for ii
ii = 1:tm + 1:tm #Evaluates to
So ii will definitely be larger than tm (and therefore length(temp) at some point.
In order to better understand/debug for loops, consider printing just the indices:
for(i in 1:tm)
{
print(i)
for(ii in i + 1:tm)
print(ii)
}
At a guess I'm going to say that this is in R - if so I'm guessing that this line:
if (temp[i] == 0) (or temp[ii] == 0)
is resulting in an NA, and if conditions must have a TRUE or FALSE value.
Using a debugger if you can, I'd interrogate the value of temp[i] before the if block.
Difficult without knowing the language, but i think the issue is that the value in ii can be greater than the length of temp when i is at its upper bound. I'd have expected an index out of range or something similar but, without knowing the language, who knows! Hope you get your problem fixed.

Resources