I am using plotFun function of mosaic package in R. I am trying to plot a 3D plot. Following is my code snippet:
plotFun(2*l*(w/log(beta*kspill*lambda^2+(1+(w/x-w)/10)*(lambda^2*5+lambda^1*5+1))+(w/x-w)/log((1+((w/x-w)/10)^1)*(lambda^2*5+lambda^1*5+1))) ~ x & lambda ,
x.lim=range(0.8,1), lambda.lim=range(1,3),
l=60,w=40,kspill=10,f=1,beta=0.5,surface=TRUE)
This is working fine. Now suppose I want to fix lambda and introduce a new variable t such that if t=2 we get lambda^2*5+lambda^1*5+1 as in the above case. If t=3 we get lambda^3*5+lambda^2*5+lambda^1*5+1 and so on. So now I have t.lim=range(1,3) for a fixed lambda :
plotFun(2*l*(w/log(beta*kspill*lambda^2+(1+(w/x-w)/10)*("depends on t"))+(w/x-w)/log((1+((w/x-w)/10)^1)*("depends on t"))) ~ x & lambda ,
x.lim=range(0.8,1), t.lim=range(0.5,1),
l=60,w=40,kspill=10,f=1,beta=0.5,lambda=1,surface=TRUE)
What to write in the "depends on t" part above. I guess we can't put a for loop there to calculate 5* {summation i=0 to i=t}lambdai. How to go about doing this?
You can define your "depends on t" with
depends_on_t <- makeFun(5 * sum(lambda^(1:round(t))) + 1 ~ t + lambda, lambda = 1)
But you still have some issues to resolve:
1) Your plotFun() command is creating a plot using x and lambda, but I'm guessing you meant x and t.
2) t can only be an integer if you are going to use it in a sum of the type you are suggesting. But you are creating a plot that assumes continuous variables for the axes. I inserted round(t) as one way to move from real values to integer values before computing the sum. The makes the function work for non-integer values, but it might not be what you really want.
Finally, some additional suggestions:
3) x & lambda should be replaced with x + lambda. The use of & here dates back to the very early days of the mosaic package, and although it is still supported (I think, we don't really test for it anymore), we prefer x + lambda.
4) I recommend separating out the definition of your function from the plotFun() command. You can use mosaic::makeFun() as illustrated above, or the usual function() to define your function and whatever default values you want for its arguments. Then you can do sanity checks on the function, or use it in multiple plots rather than including all of the function's definition in each plot.
5) Using spaces and returns would make your code much more readable. (As would simplifying your example to a minimal example that demonstrates the issue you are asking about.)
6) I think you might want
depends_on_t <- makeFun(5 * sum(lambda^(0:round(t))) ~ t + lambda, lambda = 1)
rather than the formula as you describe it, but without more context, I can't really know.
Related
I have a problem where I need to generate my own monomial sequence of N terms and evaluate it numerically - a polynomial basis, mind you.
What I need is a function that I can generate. The problem is that (as far as I know) I can't iterate over a function I have already defined in order to keep adding terms of my own devising (the monomials), which is what I want. The only way I know how to add the terms that I want is manually, but that won't do.
Basically, I want something like...
N=4
#Code runs, and then I get something like the following:
f(x) = x^0 + c1*x + c2*x^2 + c3*x^3 + c4*x^4
And I want it to be a function that can be evaluated or differentiated via other packages.
Note: I want to operate on the coefficients in order to see if I can solve a problem where I assume the polynomial is the solution that I then have to optimize.
Yes, I know the package Polynomials.jl can tackle the aforementioned example quite readily and cleanly, but what I want is to be able to define each of the terms that I keep adding to the polynomial sequence myself, make them a trigonimetric function, an exponential, etc. Maybe I want to define the Fourier series, or whatever. I want to build my own polynomial base that I can then evaluate.
Like this:
N=4
#Code runs, and then I get the following:
f(x) = x^0 + c1*cos(x) + c2*sin(x) + c3*exp(3*x) + c4*x^4
I tried with Symbolics.jl, played with Polynomials.jl, tried to get it done with varargs, and nothing worked. I am genuinely stumped. Any help would be greatly appreciated, even if just to tell me "Go learn metaprogramming," or something like that.
Maybe this can help or at least gives you an insight:
julia> function myf(x, coefs)
myExpressions = [x^0, cos(x), sin(x), exp(3*x), x^4]
#assert length(coefs) == length(myExpressions) "The length of coefficients doesn't match the length of the expressions."
return coefs*myExpressions
end
julia> myf(1, [1 2 3 4 5])
1-element Vector{Float64}:
89.94716525891064
julia> myf(1, [1 2 3 4])
ERROR: AssertionError: The length of coefficients doesn't match the length of the expressions.
I have initially posted this question on stats.stackexchange.com,
but it was closed due to being focused on programming. Hopefully, I
can get any help here.
I will not put many theoretical details here to make it simple, but my final goal is to implement a Hidden Markov Model using R.
Although I am fine with the theoretical model construction, when I tried to implement it, I realized that I do not know basic things about computational statistics. My question goes into this direction.
Let and be random variables such that and , with and . If denotes distribution, how can I compute
using R?
I mean, what is the exact meaning of these distributions (one discrete and one continuous) multiplication? How can I do this using R? The answer is obviously a function of , but how is it represented in my code?
Is there any change if is also discrete? For instance, , with . How it would affect the implemented code?
I know my questions are not very specific, but I am very lost on how to start. My goal with this question is understanding how I can "translate" what I have written in paper to the computer.
Translation
The equations describe how to compute the probability distribution of X given an observation of Y=y and values for parameters p and sigma. Ultimately, you want to implement a function p_X_given_Y that takes a value of Y and returns a probability distribution for X. A good place to start is to implement the two functions used in the RHS of the expression. Something like,
p_X <- function (x, p=0.5) { switch(as.character(x), "0"=p, "1"=1-p, 0) }
p_Y_given_X <- function (y, x, sigma=1) { dnorm(y, x, sd=sigma) }
Note that p and sigma are picked arbitrarily here. These functions can then be used to define the p_X_given_Y function:
p_X_given_Y <- function (y) {
# numerators: for each x \in X
ps <- sapply(c("0"=0,"1"=1),
function (x) { p_X(x) * p_Y_given_X(y, x) })
# divide out denominator
ps / sum(ps)
}
which can be used like:
> p_X_given_Y(y=0)
# 0 1
# 0.6224593 0.3775407
> p_X_given_Y(y=0.5)
# 0 1
# 0.5 0.5
> p_X_given_Y(y=2)
# 0 1
# 0.1824255 0.8175745
These numbers should make intuitive sense (given p=0.5): Y=0 is more likely to come from X=0, Y=0.5 is equally likely to be X=0 or X=1, etc.. This is only one way of implementing it, where the idea is to return the "distribution of X", which in this case is simply a named numeric vector, where the names ("0", "1") correspond to the support of X, and the values correspond to the probability masses.
Some alternative implementations might be:
a p_X_given_Y(x,y) that also takes a value for x and returns the corresponding probability mass
a p_X_given_Y(y) that returns another function that takes an x argument and returns the corresponding probability mass (i.e., the probability mass function)
General problem:
I have a function that takes another function as an argument, of form:
F <- function(x, FUN){FUN(x)}
I could easily pass a simple function to it:
f1 <- function(x){plot(x, 1/x)}
F(-5:5, f1)
would display a plot of 1/x.
Supposing I had another, more complex function:
f2 <- function(x, a){plot(x, 1/x^a)}
f2 has 2 arguments, so can't be passed directly to F. But I might want to retain the flexibility in a so that, without defining lots of different functions, I can quickly plot 1/x^a for whatever value of a I fancy. I've tried, for a = 2:
F(-5:5, f2(, 2))
F(-5:5, f2(, a=2))
F(-5:5, f2(x, 2))
F(-5:5, f2(a=2))
But none of these work. Does anyone have a solution? (I could set a default for a in f2, but then I could not run it with a different value of a).
Specific context:
I have a function that will find the inverse Laplace Transform of a function, taking a function as its argument which is expected to have one argument (the Laplace variable, p). I can invert a function like f1 above. But I am trying to invert a function for contaminant transport in groundwater. This process depends upon lots of other parameters such as the water velocity and the distance being travelled. So I would like to be able to pass a multi-parameter function for Laplace inversion in such a way that all parameters apart from the Laplace parameter p is fixed. Ultimately I would like to do this process many times with different values for velocity etc., so I need a fluid way to change the "fixed" parameters being used.
Thanks in advance for any help,
Christopher
Just define a generator of function:
genFunc = function(a)
{
function(x) plot(x, 1/x^a)
}
F(-5:5, genFunc(2))
Or use Curry from functional package to fix parameters you want and spice your meals:
library(functional)
F(-5:5, Curry(f2, a=2))
I want to generate sa scaled-inv-chisquared distribution in R. I know geoR have a R function for generating this. But I want to use gamma-distribution to generate this.
I think this two are equivalent:
X ~ rinvchisq(100, df=d, scale=s)
1/X ~ rgamma(100, shape=d/2, scale=2/(d*s))
isn't it? Can there be any numerical problem due this due to extreme values?
More specifically you would need X <- rinvchisq(...) and X <- 1/rgamma(...) (the ~ notation works this way in programs such as WinBUGS, and in statistics notation, but not in R). If you look at the code of geoR::rinvchisq, the relevant part is just
return((df * scale)/rchisq(n, df = df))
so if you have problems taking the reciprocal of very large or small chi-squared deviates you'll be in trouble anyway (although rchisq is internally using .External(C_rchisq, n, df), which falls through to C code, presumably for efficiency in this special case, rather than calling rgamma). If I were you I would go ahead and superimpose densities of some test samples just to make sure I hadn't screwed up the arithmetic or parameterization somewhere ...
For what it's worth there are also rinvgamma() functions in a variety of packages (library(sos); findFn("rinvgamma"))
I am trying to use the outer function with predict in some classification code in R. For ease, we will assume in this post that we have two vectors named alpha and beta each containing ONLY 0 and 1. I am looking for a simple yet efficient way to pass all combinations of alpha and beta to predict.
I have constructed the code below to mimic the lda function from the MASS library, so rather than "lda", I am using "classifier". It is important to note that the prediction method within predict depends on an (alpha, beta) pair.
Of course, I could use a nested for loop to do this, but I am trying to avoid this method.
Here is what I would like to do ideally:
alpha <- seq(0, 1)
beta <- seq(0, 1)
classifier.out <- classifier(training.data, labels)
outer(X=alpha, Y=beta, FUN="predict", classifier.out, validation.data)
This is a problem because alpha and beta are not the first two parameters in predict.
So, in order to get around this, I changed the last line to
outer(X=alpha, Y=beta, FUN="predict", object=classifier.out, data=validation.data)
Note that my validation data has 40 observations, and also that there are 4 possible pairs of alpha and beta. I get an error though saying
dims [product 4] do not match the length of object [40]
I have tried a few other things, some of which work but are far from simple. Any suggestions?
The problem is that outer expects its function to be vectorized (i.e., it will call predict ONCE with a vector of all the arguments it wants executed). Therefore, when predict is called once, returning its result (which happens to be of length 4), outer complains because it doesn't equal the expected 40.
One way to fix this is to use Vectorize. Untested code:
outer(X=alpha, Y=beta, FUN=Vectorize(predict, vectorize.args=c("alpha", "beta")), object=classifier.out, data=validation.data)
I figured out one decent way to do this. Here it is:
pairs <- expand.grid(alpha, beta)
names(pairs) <- c("alpha", "beta")
mapply(predict, pairs$alpha, pairs$beta,
MoreArgs=list(object=classifier.out, data=validation.data))
Anyone have something simpler and more efficient? I am very eager to know because I spent a little too long on this problem. :(