Hello I try to appear a plot in R with step 0.1 inside the space [0-89] and I do not know how.
The code is :
c1 = 1500
c2 = 1600
c3 = 1850
p1 = 1000
p2 = 1300
p3 = 1500
h = 100
f = 500
w = 2 *pi * f
k2 = w / c2
i = complex( real = 0, imaginary = 1 )
th1 = ( 0:89 )
th1 = th1 * pi / 180
th2 = asin( pmin(pmax((c2 / c1) * sin (th1),-1.0),1.0) )
th3 = asin(pmin(pmax(( c3 / c2) * sin (th2),-1.0),1.0) )
R12 = (p2 * c2 * cos(th1) - p1 * c1 * cos(th2) ) / (p2 * c2 * cos(th1) + p1 * c1 * cos (th2))
R23 = (p3 * c3 * cos(th2) - p2 * c2 * cos(th3)) / (p3 * c3 * cos(th2) + p2 * c2 * cos (th3))
phi2 = k2 * h * cos(th2)
R13 = (R12 + R23 * exp(2 * i * phi2 ))/ ( 1+ R12 * R23 * exp(2 * i* phi2))
y=abs(R13)
th1=th1*180/pi
plot(th1 , y, type = "l", xlab="Angle of Incidence (Deg)", ylab="|R13|")
axis(side=1, at=seq(0, 100, by=10))
axis(side=2, at=seq(0, 1, by=0.1))
The plot that I take is :
I did it in matlab and the command is t = 0:0.1:89. So if I use this step 0.1 I have a plot like this:
Can you help me on how can I make this work and in R ?
In your code th1 = ( 0:89 ) generates a sequence with a step of 1. If you change that line with th1 = seq(0,89, 0.05), the step will now be 0.05 instead of 1.
Related
I am working on a paper that requires me to find the MLE of Gumbel’s type I
bivariate exponential distribution. I have proved the likelihood and log-likelihood functions likelihood and log-likelihood but I am struggling to implement it in r to perform optimization with Optim function. My code generates NA values.
Below are my codes.
# likelihood function of x
likelihood.x = function(params, data) {
lambda1 = params[1]
lambda2 = params[2]
theta = params[3]
A = (1 - theta) * (lambda1 * lambda2)
B = theta * (lambda1 ^ 2) * lambda2 * data$X1
C = theta * lambda1 * (lambda2 ^ 2) * data$X2
D = (theta ^ 2) * (lambda1 ^ 2) * (lambda2 ^ 2) * data$X1 * data$X2
E = (lambda1 * data$X1) + (lambda2 * data$X2) + (theta * lambda1 * lambda2 * data$X1 * data$X2)
f = sum(log(A + B + C + D)) - sum(E)
return(exp(f))
}
# Log-likelihood function of x
log.likelihood.x = function(params, data){
lambda1 = params[1]
lambda2 = params[2]
theta = params[3]
A = (1 - theta) * (lambda1 * lambda2)
B = theta * (lambda1 ^ 2) * lambda2 * data$X1
C = theta * lambda1 * (lambda2 ^ 2) * data$X2
D = (theta ^ 2) * (lambda1 ^ 2) * (lambda2 ^ 2) * data$X1 * data$X2
E = (lambda1 * data$X1) + (lambda2 * data$X2) + (theta * lambda1 * lambda2 * data$X1 * data$X2)
f = sum(log(A + B + C + D)) - sum(E)
return(-f)
}
Here's the function for generating the data
# Simulating data
rGBVE = function(n, lambda1, lambda2, theta) {
x1 = rexp(n, lambda1)
lambda12 = lambda1 * lambda2
pprod = lambda12 * theta
C = exp(lambda1 * x1)
A = (lambda12 - pprod + pprod * lambda1 * x1) / C
B = (pprod * lambda2 + pprod ^ 2 * x1) / C
D = lambda2 + pprod * x1
wExp = A / D
wGamma = B / D ^ 2
data.frame(x1, x2 = rgamma(n, (runif(n) > wExp / (wExp + wGamma)) + 1, D))
}
data = rGBVE(n=100, lambda1 = 1.2, lambda2 = 1.4, theta = 0.5)
colnames(data) = c("X1", "X2")
My goal is to find MLE for lambda1, lambda2 and theta using Optim() in r.
Kindly assist me to implement my likelihood and log-likelihood function in r.
Thank you.
Your concern appears to be about the warning message
In log(A+B+C+D): NaNs produced
Such warnings are usually harmless — it just means that the optimization algorithm tried a set of parameters somewhere along the way that violated the condition A+B+C+D ≥ 0. Since these are reasonably complex expressions it would take a little bit of effort to figure out how one might constrain the parameters (or reparameterize the function, e.g. fitting some of the parameters on the log scale) to avoid the warning, but taking a guess that keeping the parameters non-negative will help, we can try using the L-BFGS-B algorithm (which is the only algorithm available in optim() that allows multidimensional bounded optimization).
r1 <- optim(par = c(1,2,1),
fn = log.likelihood.x,
dat = data)
r2 <- optim(par = c(1,2,1),
fn = log.likelihood.x,
lower = rep(0,3),
method = "L-BFGS-B",
dat = data)
The second does not generate warnings, and the results are close (if not identical):
all.equal(r1$par, r2$par)
## "Mean relative difference: 0.0001451953"
You might want to use bbmle, which has some additional features for likelihood modeling:
library(bbmle)
fwrap <- function(x) log.likelihood.x(x, dat = data)
parnames(fwrap) <- c("lambda1", "lambda2", "theta")
m1 <- mle2(fwrap, start = c(lambda1 = 1, lambda2 = 2, theta = 1), vecpar = TRUE,
method = "L-BFGS-B", lower = c(0, 0, -0.5))
pp <- profile(m1)
plot(pp)
confint(pp)
confint(m1, method = "quad")
Hey I have following code in R
S0 = 40
r = log(1 + 0.07)
sigma = 0.3
K = 45
n_steps_per_year = 4
dt = 1 / n_steps_per_year
T = 3
n_steps = n_steps_per_year * T
R = n_paths
Q = 70
P = 72
n_paths = P * Q
d = exp(-r * dt)
N = matrix(rnorm(n_paths * n_steps, mean = 0, sd = 1), n_paths, n_steps)
paths_S = matrix(nrow = n_paths, ncol = n_steps + 1, S0)
for(i in 1:n_paths){
for(j in 1:n_steps){
paths_S[i, j + 1] = paths_S[i, j] * exp((r - 0.5 * sigma ^ 2) * dt + sigma * sqrt(dt) * N[i, j])
}
}
I = apply(K - paths_S, c(1,2), max, 0)
V = matrix(nrow = n_paths, ncol = n_steps + 1)
V[, n_steps + 1] = I[, n_steps + 1]
dV = d * V[, n_steps + 1]
model = lm(dV ~ poly(paths_S[, n_steps], 10))
pred = predict(model, data.frame(x = paths_S[, n_steps]))
plot(paths_S[, n_steps], d * V[, n_steps + 1])
lines(paths_S[, n_steps], pred)
but when I run the last two lines then I get very strange plot (multiple lines instead of one line). What is going on?
You did not provide n_paths, lets assume:
n_paths = 7
set.seed(111)
Then running your code, before you plot, you need to order your x values before plotting:
o = order(paths_S[,12])
plot(paths_S[o, n_steps], d * V[o, n_steps + 1],cex=0.2,pch=20)
lines(paths_S[o, n_steps], pred[o],col="blue")
I'm trying to fit data with nls() function where the nature of data gives me bounds for one coefficient and for sum of two coefficients. Let me introduce short example to see where is the problem. I want parameter b1 to be between 0 and 1 and I want sum of parameters b1 and b2 to be between 0 and 1 as well.
set.seed(123)
# example where everything is OK
x <- 1:200
g <- rbinom(200, 1, 0.5)
y <- 3 + (0.7 + 0.2 * g) * x
yeps <- y + rnorm(length(y), sd = 0.1)
# both parameter b1 and sum of parameters b1 and b2 are between 0 and 1
nls(yeps ~ a + (b1 + b2 * g) * x, start = list(a = 0.12345, b1 = 0.54321, b2 = 0.4213))
# using more extreme values
x <- 1:200
g <- rbinom(200, 1, 0.5)
y <- 3 + (0.9 - 0.99 * g) * x
yeps <- y + rnorm(length(y), sd = 15)
# b1 is OK, but b1 + b2 < 0
nls(yeps ~ a + (b1 + b2 * g) * x,
start = list(a = 0.12345, b1 = 0.54321, b2 = 0.4213))
# trying constraints, not good, sum is still out of range
nls(yeps ~ a + (b1 + b2 * g) * x,
start = list(a = 0.12345, b1 = 0.54321, b2 = 0.4213),
lower = list(a = -Inf, b1 = 0, b2 = -1),
upper = list(a = Inf, b1 = 1, b2 = 1),
algorithm = "port")
What I'm looking for is something like that (does not work):
nls(yeps ~ a + (b1 + b2 * g) * x,
start = list(a = 0.12345, b1 = 0.54321, b2 = 0.4213),
lower = list(a = -Inf, b1 = 0, b2 = -b1),
upper = list(a = Inf, b1 = 1, b2 = 1 - b1),
algorithm = "port")
Is it possible to set constraints with other parameters in nls() function? Thanks for any suggestions!
Let B2 = b1+b2 so b2 = B2-b1 and substituting B2-b1 for b2 we get a problem in terms of a, b1 and B2 of which the latter two are between 0 and 1 so:
fm <- nls(yeps ~ a + (b1 + (B2-b1) * g) * x, lower = c(-Inf, 0, 0), upper = c(Inf, 1, 1),
start = list(a = 0.1, b1 = 0.5, B2 = 0.1), alg = "port")
giving the following (hence b2 = B2 - b1 = 0 - 0.9788 = -0.9788)
> fm
Nonlinear regression model
model: yeps ~ a + (b1 + (B2 - b1) * g) * x
data: parent.frame()
a b1 B2
-5.3699 0.9788 0.0000
residual sum-of-squares: 42143
Algorithm "port", convergence message: both X-convergence and relative convergence (5)
and plotting:
plot(yeps ~ x)
points(fitted(fm) ~ x, pch = 20, col = "red")
When P1 changes from (0,4) to (0,2), Q1(t=0.5) and Q2(t=0.6) move 0.75 and 0.576 respectively. How can I calculate for any B(t) the distance it moves when P1 or P2 move along (Start--P1) or (P2--End) respectively?
Just write Bezier curve expression:
B(t) = P0 * (1-t)^3 + P1 * 3 * t * (1-t)^2 + P2 * 3 * t^2 * (1-t) + P3 * t^3
Let's P1' is new position of P1 control point. Only the second term will be changed, so
DeltaB(t) = B'(t) - B(t) = (P1' - P1) * 3 * t * (1-t)^2
if P1' lies on P0-P1, then
P1' = P0 + (P1 - P0) * u
DeltaB(t) = (P0 + (P1 - P0) * u - P1) * 3 * t * (1-t)^2 =
(P0 - P1) * (1 - u) * 3 * t * (1-t)^2
For your example data
u = 0.5
(P0 - P1) * (1 - u) = (0, -2) // (x,y) components of vector
DeltaB(0.5) = (0, -2 * 3 * 0.5 * 0.25) = (0, -0.75)
DeltaB(0.6) = (0, -2 * 3 * 0.6 * 0.4 * 0.4) = (0, -0.576)
I am trying to find the easiest way to determine a relative position of a point within a quadrilateral. The known are (see figure) the positions of points 1, 2, 3, 4 and 5 in the xy-coordinate system: x1, y1, x2, y2, x3, y3, x4, y4, x5, y5.
Also known are the positions of points 1, 2, 3, and 4 in the ξ-η coordinate systems (see figure).
From this data, I want to determine what are the ξ and η for point 5.
Results
Thank you to all who anwsered! I find the solution by #dbc and #agentp similar. Also I find this solution better than the perspective transformation solution by #MBo, since I do not have to compute the inverse of a matrix (Ax=B --> x=inv(A)*B).
I get the following result for:
u = 0.5 * (ξ + 1)
v = 0.5 * (η + 1)
In my case all points are within the rectangle, therefore u>0 and v>0.
What you have here is a 2d bilinear blended surface. For simplicity, let's change its coordinates to range from zero to one:
u = 0.5 * (ξ + 1)
v = 0.5 * (η + 1)
In that case, the surface evaluator can be expressed as
F(u, v) = P1 + u * (P2 - P1) + v * ((P4 + u * (P3 - P4)) - (P1 + u * (P2 - P1)))
I.e., for a given u, construct a line passing through the following two points:
Pv0 = P1 + u * (P2 - P1);
Pv1 = P4 + u * (P3 - P4);
then interpolate between then for given v
F(u, v) = Pv0 + v * (Pv1 - Pv0)
What you seek are values (u,v) such that F(u, v) = P5. This will occur for given u when the line from Pv0 to Pv1 passes through P5, which will occur when P5 - Pv0 is parallel to Pv1 - Pv0 -- i.e. when their 2d cross is zero:
cross2d(P5 - Pv0, Pv1 - Pv0) = 0
⇒
cross2d(P5 - (P1 + u * (P2 - P1)),
P4 + u * (P3 - P4) - (P1 + u * (P2 - P1))) = 0
Now, the 2d cross of two 2d vectors A ⨯ B is given by Ax*By - Ay*Bx, so that equation becomes
(x5 - (x1 + u * (x2 - x1))) * (y4 + u * (y3 - y4) - (y1 + u * (y2 - y1))) - (y5 - (y1 + u * (y2 - y1))) * (x4 + u * (x3 - x4) - (x1 + u * (x2 - x1))) = 0
Expanding this expression out and collecting collecting together terms in u, we get
u^2 * (x1*y3 - x1*y4 - x2*y3 + x2*y4 + (-x3)*y1 + x3*y2 + x4*y1 - x4*y2)
+ u * (-x1*y3 + 2*x1*y4 - x1*y5 - x2*y4 + x2*y5 + x3*y1 - x3*y5 - 2*x4*y1 + x4*y2 + x4*y5 + x5*y1 - x5*y2 + x5*y3 - x5*y4)
+ (-x1*y4 + x1*y5 + x4*y1 - x4*y5 - x5*y1 + x5*y4)
= 0
This is now a quadratic equation over u, and can be solved as such. Note that in cases where the top and bottom edges of your quadrilateral are parallel then the quadratic devolves into a linear equation; your quadratic equation solver must needs handle this.
double a = (x1 * y3 - x1 * y4 - x2 * y3 + x2 * y4 + (-x3) * y1 + x3 * y2 + x4 * y1 - x4 * y2);
double b = (-x1 * y3 + 2 * x1 * y4 - x1 * y5 - x2 * y4 + x2 * y5 + x3 * y1 - x3 * y5 - 2 * x4 * y1 + x4 * y2 + x4 * y5 + x5 * y1 - x5 * y2 + x5 * y3 - x5 * y4);
double c = (-x1 * y4 + x1 * y5 + x4 * y1 - x4 * y5 - x5 * y1 + x5 * y4);
double[] solutions = Quadratic.Solve(a, b, c);
There may be more than one solution. There might also be no solutions for a degenerate quadrilateral.
Having solved for value(s) of u, finding the equivalent v is straightforward. Given points
Pv0 = P1 + u * (P2 - P1);
Pv1 = P4 + u * (P3 - P4);
you seek v such that
v * (Pv1 - Pv0) = P5 - Pv0;
Pick the coordinate index 0 or 1 such that |(Pv1 - Pv0)[index]| is maximized. (If both coordinates are almost zero, then give up -- there's no solution for this specific u. Then set
v = (P5 - Pv0)[index] / (Pv1 - Pv0)[index];
Finally, if you have more that one solution, prefer a solution inside the [u, v] boundaries of the blend. Then finally set
ξ = 2 * u - 1;
η = 2 * v - 1;
This looks like a standard finite element parameterization
(The question doesn't specify a particular mapping, but I imagine someone might be interested in this specific case)
{x, y} == (
(1 - eta) (1 - ci) {p1x, p1y} +
(1 - eta) (1 + ci) {p2x, p2y} +
(1 + eta) (1 + ci) {p3x, p3y} +
(1 + eta) (1 - ci) {p4x, p4y} )/4
This can be solved in closed form for {eta,ci}, but the expression is pretty unwieldy to post.
In practice, compute these constants:
ax = p1x + p2x + p3x + p4x
bx = p1x - p2x - p3x + p4x
cx = p1x + p2x - p3x - p4x
dx = p1x - p2x + p3x - p4x
ay = p1y + p2y + p3y + p4y
by = p1y - p2y - p3y + p4y
cy = p1y + p2y - p3y - p4y;
dy = p1y - p2y + p3y - p4y;
Solve this quadratic for eta :
(ax by - bx ay) - 4 (by x - bx y) +
eta (dx ay - cx by + bx cy - ax dy + 4 (x dy - dx y)) +
eta^2 (cx dy - dx cy) == 0
then get ci as:
ci = ((-ax + eta cx + 4 x)/(-bx + eta dx))
If the polygon is not too distorted just one of the solutions will satisfy -1<eta<1 and -1<ci<1
Referring to the self-answer of #blaz (please vote up the answers of #blaze, #dbc and #agentp)
For everybody who is not willing to copy the formulas by hand, here is the formula as C# code:
double v_sqrt = Math.Sqrt(
4 * (
(x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4)) * (x4 * (-1 * y + y1) + x1 * (y - y4) + x * (-1 * y1 + y4)) +
Math.Pow(
(x3 * y - x4 * y - x3 * y1 + 2 * x4 * y1 - x4 * y2 + x1 * (y + y3 - 2 * y4) + x2 * (-1 * y + y4) + x * (-1 * y1 + y2 - y3 + y4))
, 2)
);
double u_sqrt = Math.Sqrt(
4 * ((x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4))
* (
x4 * (-1 * y + y1) + x1 * (y - y4) + x * (-1 * y1 + y4)
) +
Math.Pow(
(x3 * y - x4 * y - x3 * y1 + 2 * x4 * y1 - x4 * y2 + x1 * (y + y3 - 2 * y4) + x2 * (-1 * y + y4) + x * (-1 * y1 + y2 - y3 + y4))
, 2)
);
double k = 1 / (2 * ((x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4)));
double l = 1 / (2 * ((x1 - x4) * (y2 - y3) - (x2 - x3) * (y1 - y4)));
///////////////////////////////////////////////////////////////////////////////////////////////
double v1 = l *
(x2 * y - x3 * y + x4 * y + x * y1 - 2 * x2 * y1 + x3 * y1 - x * y2 - x4 * y2 + x * y3 - x1 * (y - 2 * y2 + y3) - x * y4 + x2 * y4 +
v_sqrt);
///////////////////////////////////////////////////////////////////////////////////////////////
double u1 = -1 * k *
(-x2 * y + x3 * y - x * y1 - x3 * y1 + 2 * x4 * y1 + x * y2 - x4 * y2 - x * y3 + x1 * (y + y3 - 2 * y4) + x * y4 + x2 * y4 +
u_sqrt);
double v2 = -1 * l *
(x1 * y + x3 * y - x4 * y - x * y1 - 2 * x3 * y1 + x * y2 - -2 * x1 * y2 + x4 * y2 - x * y3 + x1 * y3 + x * y4 - x2 * (y - 2 * y1 + y4) +
v_sqrt);
/////////////////////////////////////////////////////////////////////////////////////////////////
double u2 = k *
(x2 * y - x3 * y + x4 * y + x * y1 + x3 * y1 - 2 * x4 * y1 - x * y2 + x4 * y2 + x * y3 - x1 * (y + y3 - 2 * y4) - x * y4 - x2 * y4 +
u_sqrt);
In most cases it is u1 and v1 so there should not be the need for computing the other ones.
I used it to calibrate the coordinates of a Pegasus Air-Pen device (ultrasonic stylus) on a sheet of paper. It does work best if your coordinates for point 1 to 5 are also >= 0.
Sry for posting this as an answer but it is too long for a comment and I think it is a valuable help for this post as it would be for me.
You need to calculate a matrix of perspective transformation, that maps 4 points of source quadrilateral to 4 points of destination quadrilateral (example) (more mathemathics), then apply this transformation to coordinates of 5th point (multiply matrix by coordinate vector)