IDL lambda: Attempt to subscript is out of range - idl-programming-language

idl 8.4 introduced the lambda function. I have IDL 8.6.1 and the lambda function does not fully work as documented:
IDL> f = lambda(x : x * x)
IDL> print, call_function(f, findgen(10))
0.00000 1.00000 4.00000 9.00000 16.0000 25.0000 36.0000 49.0000 64.0000
81.0000
IDL> print, f(findgen(10))
IDL$LAMBDAF5 IDL$LAMBDAF5 IDL$LAMBDAF5 IDL$LAMBDAF5 IDL$LAMBDAF5 IDL$LAMBDAF5 IDL$LAMBDAF5 IDL$LAMBDAF5 IDL$LAMBDAF5
IDL$LAMBDAF5
IDL> print, f(5)
% Attempt to subscript F with <INT ( 5)> is out of range.
So, why f(5) does not return 25?

Oh, as commented here, this is documented.
Note: To make direct calls on a Lambda function, you should make sure that compile_opt strictarr (or compile_opt idl2) is turned on so that IDL interprets the parentheses as a function call instead of array indices. See COMPILE_OPT for details.
So
compile_opt strictarr
or
compile_opt idl2.
However, I would have expected that direct calls are possible by default.

Related

R function and pass optional arguments

I create a R function like:
myfun <- function(x, function) function(x)
which obviously works now is for example
myfun(rnorm(10), round)
myfun(rnorm(10), sample)
Is it possible to pass over the argument digits from the function round without specifying it in myfun?
Or pass over the argument replace from the function sample?
Something like
myfun(rnorm(10), round(digits=2))
myfun(rnorm(10), sample(replacement=TRUE))
I know it looks strange. I want to write a function where i can choose the distribution in the body.
myfun <- function(n, function) function(n)
now myfun(100,rnorm) works of course, but can i use it for
myfun(100,rt) and define the degrees of freedom with argument df or
myfun(100,rbinom) and define the size and prob?
I think you are looking for ....
myfun <- function(x,function2, ...){function2(x,...)}
myfun(rnorm(10),round,digits=2)
[1] -1.70 1.34 1.27 -0.42 -1.76 -0.40 0.59 1.10 0.41 -0.18

Unable to produce values of a kernel density estimator in R

I'm simulating random numbers from the exponential distribution with rate=1. I have plotted a kernel density of the data using the density() function in R. What I want is a function f that gives me the value of the density at any point. I have tried the following code:
n=10^5
x=rexp(n,rate=1)
d=density(x,kernel="gaussian")
f=function(x){d$y[x]}
f(1)
plot(d)
However,
f(1) clearly does not match the value of the density function at the point x=1. Where am I going wrong?
density produces a list which contains, in field x, the coordinates of the points at which the density is evaluated and, in field y, the estimated values of the density at these coordinates:
> str(d)
List of 7
$ x : num [1:512] -0.348 -0.328 -0.307 -0.286 -0.266 ...
$ y : num [1:512] 0.00146 0.00256 0.00435 0.00717 0.01147 ...
......
To get a function from x and y, you can use the approxfun function:
> f <- approxfun(d$x, d$y)
> f(1)
[1] 0.3665273
> dexp(1, rate=1)
[1] 0.3678794
In your code you get d$y[1], which is the first value of d$y.

Integration of a function of 2 arguments where 1 argument is a random vector

I have a function func (in R) of 2 variables defined like this (just an example):
func <- function(t,gam){return(exp(-t/2)*(t+1)^gam)}
The second argument gam will be estimated from 2 different sample so basically gam is a vector of length 2. What I want to receive is the integration of this function for t: 0->Inf when gam is known.
I tried few ways but could not get a vector of values from integration. Any advice will be very much appreciated. Thanks a lot.
Need to use sapply to deliver the two item vector (separately) to integrate:
sapply( gam, function(x) integrate( func, lower=0,upper=Inf, gam=x)$value )
Example:
> sapply( c(.5,1), function(x) integrate( func, lower=0,upper=Inf, gam=x)$value )
[1] 3.311359 6.000000

better way to calculate euclidean distance with R

I am trying to calculate euclidean distance for Iris dataset. Basically I want to calculate distance between each pair of objects. I have a code working as follows:
for (i in 1:iris_column){
for (j in 1:iris_row) {
m[i,j] <- sqrt((iris[i,1]-iris[j,1])^2+
(iris[i,2]-iris[j,2])^2+
(iris[i,3]-iris[j,3])^2+
(iris[i,4]-iris[j,4])^2)
}
}
Although this works, I don't think this is a good way to wring R-style code. I know that R has built-in function to calculate Euclidean function. Without using built-in function, I want to know better code (faster and fewer lines) which could do the same as my code.
The part inside the loop can be written as
m[i, j] = sqrt(sum((iris[i, ] - iris[j, ]) ^ 2))
I’d keep the nested loop, nothing wrong with that here.
Or stay with the standard package stats:
m <- dist(iris[,1:4]))
This gives you an object of the class dist, which stores the lower triangle (all you need) compactly. You can get an ordinary full symmetric matrix if, e.g., you like to look at some elements:
> as.matrix(m)[1:5,1:5]
1 2 3 4 5
1 0.0000000 0.5385165 0.509902 0.6480741 0.1414214
2 0.5385165 0.0000000 0.300000 0.3316625 0.6082763
3 0.5099020 0.3000000 0.000000 0.2449490 0.5099020
4 0.6480741 0.3316625 0.244949 0.0000000 0.6480741
5 0.1414214 0.6082763 0.509902 0.6480741 0.0000000

Error in Weibull distribution

file.data has the following values to fit with Weibull distribution,
x y
2.53 0.00
0.70 0.99
0.60 2.45
0.49 5.36
0.40 9.31
0.31 18.53
0.22 30.24
0.11 42.23
Following the Weibull distribution function f(x)=1.0-exp(-lambda*x**n), it is giving error:
fit f(x) 'data.dat' via lambda, n
and finally plotting f(x) and xy graph have large discrepancy.
Any feedback would be highly appreciated. Thanks!
Several things:
You must skip the first line (if it really is x y).
You must use the correct function (the pdf and not the CDF, see http://en.wikipedia.org/wiki/Weibull_distribution, like you did in https://stackoverflow.com/q/20336051/2604213)
You must use an additional scaling parameter, because your data are not normalized
You must select adequate initial values for the fitting.
The following works fine:
f(x) = (x < 0 ? 0 : a*(x/lambda)**(n-1)*exp(-(x/lambda)**n))
n = 0.5
a = 100
lambda = 0.15
fit f(x) 'data.dat' every ::1 via lambda, n, a
set encoding utf8
plot f(x) title sprintf('λ = %.2f, n = %.2f', lambda, n), 'data.dat' every ::1
That gives (with 4.6.4):
If that's the actual command you provided to gnuplot, it won't work because you haven't yet defined f(x).

Resources