Complex numbers and missing arguments in R function - r

I am solving a task for my R online course. The task is to write a function, that solves the quadratic equation with the Lagrange resolvents, or:
x1<--p/2+sqrt((p/2)^2-q)
x2<--p/2-sqrt((p/2)^2-q)
1) If the arguments are non-numeric, the function should return an explained error (or why the error has happend). 2) If there are missing arguments, the function should return an explained error (different from the default). 3) If x1 and x2 are complex numbers (for example if p=-4 and q=7, then x1=2+i*1.73 and x2=2-i*1.73), the function should should also solve the equation instead of generating NaNs and return a warning message, that the numbers are complex. Maybe if I somehow cast it to as.complex, but I want this to be a special case and don't want to cast the basic formula.
My function looks like this:
quadraticEquation<-function(p,q){
if(!is.numeric(c(p,q)))stop("p and q are not numeric") #partly works
if(is.na(c(p,q)))stop("there are argument/s missing") #does not work
x1<--p/2+sqrt((p/2)^2-q)
x2<--p/2-sqrt((p/2)^2-q)
#x1<--p/2+sqrt(as.complex((p/2)^2-q)) works, but I want to perform this only in case the numbers are complex
#x2<--p/2-sqrt(as.complex((p/2)^2-q))
return (c(x1,x2))
}
When testing the function:
quadraticEquation(4,3) #basic case is working
quadraticEquation(TRUE,5) #non-numeric, however the if-statement is not executed, because it assumes that TRUE==1
quadraticEquation(-4,7) #complex number
1) how to write the function, so it assumes TRUE (without "") and anything that is non-numeric as non-numeric?
2) basic case, works.
3) how can I write the function, so it solves the equation and prints the complex numbers and also warns that the numbers are complex (warning())?

Something like this?
quadraticEquation <- function(p, q){
## ------------------------% chek the arguments %---------------------------##
if(
missing(p) | missing(q) # if any of arguments is
){ # missing - stop.
stop("[!] There are argument/s missing")
}
else if(
!is.numeric(p) | !is.numeric(q) | any(is.na(c(p, q))) # !is.numeric(c(1, T))
){ # returns TRUE - conver-
stop("[!] Argument/s p or/and q are not numeric") # tion to the same type
}
## --------------------% main part of the function %--------------------------##
r2 <- p^2 - 4*q # calculate r^2,
if(r2 < 0){ # if r2 < 0 (convert) it
warning("equation has complex roots") # to complex and warn
r2 <- as.complex(r2)
}
# return named roots
setNames(c(-1, 1) * sqrt(r2)/2 - p/2, c("x1", "x2"))
}
quadraticEquation() # No arguments provided
#Error in quadraticEquation() : [!] There are argument/s missing
quadraticEquation(p = 4) # Argument q is missing
#Error in quadraticEquation(p = 4) : [!] There are argument/s missing
quadraticEquation(p = TRUE, q = 7) # p is logical
#Error in quadraticEquation(p = TRUE, q = 7) :
#[!] Argument/s p or/and q are not numeric
quadraticEquation(p = NA, q = 7) # p is NA
#Error in quadraticEquation(p = NA, q = 7) :
#[!] Argument/s p or/and q are not numeric
quadraticEquation(p = 7, q = -4) # real roots
# x1 x2
#-7.5311289 0.5311289
quadraticEquation(p = -4, q = 7) # complex roots
# x1 x2
#2-1.732051i 2+1.732051i
#Warning message:
#In quadraticEquation(p = -4, q = 7) : equation has complex roots

When you write is.numeric(c(p, q)), R first evaluates c(p, q) before determining whether it is numeric or not. In particular if p = TRUE and q = 3, then c(p, q) is promoted to the higher type: c(1, 3).
Here is a vectorized solution, so if p and q are vectors instead of scalars the result is also a vector.
quadraticEquation <- function(p, q) {
if (missing(p)) {
stop("`p` is missing.")
}
if (missing(q)) {
stop("`q` is missing.")
}
if (!is.numeric(p)) {
stop("`p` is not numeric.")
}
if (!is.numeric(q)) {
stop("`q` is not numeric.")
}
if (anyNA(p)) {
stop("`p` contains NAs.")
}
if (anyNA(q)) {
stop("`q` contains NAs.")
}
R <- p^2 / 4 - q
if (min(R) < 0) {
R <- as.complex(R)
warning("Returning complex values.")
}
list(x1 = -p / 2 + sqrt(R),
x2 = -p / 2 - sqrt(R))
}
Also, you should never write x1<--p/2. Keep spaces around infix operators: x1 <- -p/2.

Related

Double integration with a differentiation inside in R

I need to integrate the following function where there is a differentiation term inside. Unfortunately, that term is not easily differentiable.
Is this possible to do something like numerical integration to evaluate this in R?
You can assume 30,50,0.5,1,50,30 for l, tau, a, b, F and P respectively.
UPDATE: What I tried
InnerFunc4 <- function(t,x){digamma(gamma(a*t*(LF-LP)*b)/gamma(a*t))*(x-t)}
InnerIntegral4 <- Vectorize(function(x) { integrate(InnerFunc4, 1, x, x = x)$value})
integrate(InnerIntegral4, 30, 80)$value
It shows the following error:
Error in integrate(InnerFunc4, 1, x, x = x) : non-finite function value
UPDATE2:
InnerFunc4 <- function(t,L){digamma(gamma(a*t*(LF-LP)*b)/gamma(a*t))*(L-t)}
t_lower_bound = 0
t_upper_bound = 30
L_lower_bound = 30
L_upper_bound = 80
step_size = 0.5
integral = 0
t <- t_lower_bound + 0.5*step_size
while (t < t_upper_bound){
L = L_lower_bound + 0.5*step_size
while (L < L_upper_bound){
volume = InnerFunc4(t,L)*step_size**2
integral = integral + volume
L = L + step_size
}
t = t + step_size
}
Since It seems that your problem is only the derivative, you can get rid of it by means of partial integration:
Edit
Not applicable solution for lower integration bound 0.

How to optimize multiple arrays in R?

I need minimize a funtion based in Hsieh Model, using R language. The main objective is to minimize a distance function that depends on a set of other functions.
obj = function(x1){
s = sf()
h_til = h_tilf()
w_til = w_tilf(x1)
w_r = w_rf()
p_ir = p_irf()
#H_tr = H_trf(x1)
W = Wf(x1)
f1 = matrix(0, i, r)
f2 = matrix(0, i, r)
for (c in 1:i){
for (j in 1:r){
f1[c, j] = ( (W[c, j] - W_t[c, j]) / W_t[c, j] ) ** 2
f2[c, j] = ( (p_ir[c, j] - p_t[c, j]) / p_t[c, j] ) ** 2
}
}
d1 = sum(f1)
d2 = sum(f2)
D = d1 + d2
return(D)
}
Therefore, my algorithm must find three parameters (w, tau_w, tau_h) that minimize this distance function. These three parameters are arrays with i rows and r columns. Given by:
w = runif(i*r, 0, 1)
tau_w = runif(i*r, -1, 1)
tau_h = runif(i*r, -1, 1)
x1 = array( c(tau_w, tau_h, w), dim = c(i, r, 3))
I trying solve this using optimx and Rsolnp libraries.
res = optim(x1, #starting values
obj) #function to optimise
But i get this error:
Error in x1[c, j, 1] : incorrect number of dimensions
This minimization is usually done using the Nelder-Mead algorithm.
I'm beginner in optimization and apreciate any help. My complete code is here.
The dimensions of the array x1 are lost when you do optim(x1, obj). So the error you get is returned by w_tilf(x1) because it involves x1[c,j,1].
Reconstruct the array at the beginning of the obj function:
obj = function(x1){
x1 = array(x1, dim = c(i, r, 3))
s = sf()
......
}
Then opt <- optim(x1, obj) should work now. It will return the solution in the opt$par field as a vector, you will have to do array(opt$par, dim = c(i, r, 3)) to get an array.

How to solve this integral in R?

I need to find evaluate the following function, including an integral, in R:
Probability density functions involving multiple variables, where u = t - y.
The problem I'm running into is that while the input variables of the function as a whole are x and t, the integral needs to be evaluated over the variable u = t - y. The functions f and m' both return values, but I don't know how to make it so that R evaluates the integral over this u rather than x or T.
I currently have the following, but this doesn't return the values I'm supposed to be getting, so I'm wondering if I did it properly?
Thank you in advance!
a = 3
b = 10
T = 2.6
mprime = function(x){
return (1/x)
}
f = function(x){
if (a <= x & x <= b){
return (1/(b-a))
}
else{
return (0)
}
}
toIntegrate = function(u){
return (f(u + x)*mprime(T-u))
}
solution = function (x, T){
return (f(T + x)) + (integrate(toIntegrate(T-y), 0, T))
}
solution(5,T)
There are a few errors in your code:
f and other functions you'll be using in your integration need to be vectorised, i.e. it should take a vector as an input and return a vector as an output.
toIntegrate uses x which is neither a global variable nor an argument.
return is a function, so only the expression between parentheses are returned. As a result, your integral would not be evaluated because your function would return f(T+x)
The first argument to integrate should be toIntegrate, not toIntegrate(T-y)
mprime will return infinity for u=t, so the limits may need to be adjusted.
a = 3
b = 10
t = 2.6
mprime = function(x){
return (1/x)
}
f = function(x){
ifelse(a <= x & x <= b,1/(b-a),0)
}
toIntegrate = function(u,x,t){
return (f(u + x)*mprime(t-u))
}
solution = function (x, t){
return(f(t + x) + integrate(toIntegrate, 0, t,x=x,t=t,stop.on.error = F)$value)
}
solution(5,T)

R mknapsack function

I run the R program from article where used mknapsack function from adagio package, and everything's good. But if I want using a random values I get an error "Error condition raised".
I have a program:
n=16
m=5
max=700
min = 10
planks_we_have = floor(runif(n=m, min = 100, max = max))
planks_we_want = floor(runif(n=n, min = min, max = 16))
library(adagio)
# mknapsack calling signature is: mknapsack(values, weights, capacities)
solution <- mknapsack(planks_we_want, planks_we_want, planks_we_have)
# Above I added +1 cm to each length to compensate for the loss when sawing.
solution$ksack
# Now pretty printing what to cut so that we don't make mistakes...
assignment <- data.frame(cut_this = planks_we_have[solution$ksack], into_this = planks_we_want)
t(assignment[order(assignment[,1]), ])
Result:
Warning
In mknapsack(planks_we_want, planks_we_want, planks_we_have) :
Error condition raised: check input data ...!
Error
In data.frame(cut_this = planks_we_have[solution$ksack], into_this = planks_we_want) :
Arguments imply different numbers of lines: 0, 5
I don't understand what is the reason. The source code of the knapsack function gives me nothing:
function (p, w, k, bck = -1)
{
stopifnot(is.numeric(p), is.numeric(w), is.numeric(k))
if (any(w <= 0))
stop("'weights' must be a vector of positive numbers.")
if (any(p <= 0))
stop("'profits' must be a vector of positive numbers.")
if (any(floor(p) != ceiling(p)) || any(floor(w) != ceiling(w)) ||
any(floor(k) != ceiling(k)) || any(p >= 2^31) || any(w >=
2^31) || any(k >= 2^31))
stop("All inputs must be positive integers < 2^31 !")
n <- length(p)
m <- length(k)
if (length(w) != n)
stop("Profit 'p' and weight 'w' must be vectors of equal length.")
xstar <- vector("integer", n)
vstar <- 0
num <- 5 * m + 14 * n + 4 * m * n + 3
wk <- numeric(n)
iwk <- vector("integer", num)
S <- .Fortran("mkp", as.integer(n), as.integer(m), as.integer(p),
as.integer(w), as.integer(k), bs = as.integer(bck),
xs = as.integer(xstar), vs = as.integer(vstar), as.numeric(wk),
as.integer(iwk), as.integer(num), PACKAGE = "adagio")
if (S$vs < 0)
warning("Error condition raised: check input data ...!")
return(list(ksack = S$xs, value = S$vs, btracks = S$bs))
}
Versions:
R - 3.4.1
Adagio - 0.7.1
Please read first the help page if you have problems with a function. Looking at the solution returned, it has error code vs=-7 and help says "vs=-7 if array k is not correctly sorted". Sorting the vector of capacities may give another error, for instance in case all items can be put in one knapsack. Of course, all this depends on the random numbers generated (better fix random numbers before asking).

Writing a square root function in R

I'm trying to write a square root function in R. The function is supposed to behave like sqrt() but not use that function of course. I'm supposed to use Newton's method for computing the square root, which is:
y(a+1) = [y(a) + x / y(a)]/2
Here x is the number I'm trying to calculate the square root of and y(0) would be the initial guess of the square root of x.
The function is supposed to take in four arguments: x (the number I'm trying to compute the square root of), eps (the difference in value between iterations that are considered be equal), iter (the max number of iterations), and verbose (says I want to output intermediate results).
My issue is that I am not very well versed in writing functions in R. I have experience in C++, but they are slightly different in R.
I believe I'm supposed to write something that goes like this.
Asks the user to input a number as a guess for the value we want to calculate the square root of. Make a for loop from 1 to iter with two if statements 1) that stop the function and output the y value if the max number of iterations have been reached 2) stop the function and output the y value if the difference between successive iterations is less than eps.
Here is the code I have so far:
MySqrt <- function (x, eps = 1e-6, iter = 100, verbose = TRUE) {
for (i in 0:itmax) {
y[0] <- readline(prompt="Please enter your initial square root guess: ")
y[i + 1] = (y[i] + x / y[i])/2
if (i == 100) {
stop (return(y[i + 1]))
}
if (abs(y[i + 1] - y[i]) < eps) {
stop (return(y[i + 1]))
}
}
return(y[i + 1])
}
Here is the error I receive after entering the initial square root guess: Error in y[0] <- readline(prompt = "Please enter your initial square root guess: ") :
object 'y' not found
Honestly, I didn't expect the code to work because I'm sure there are more than one errors.
You should use iter instead of itmax.
I initialized y within the function and input of y should be formatted as a number instead of a character. You could also simplify the if statement by using | (or).
I also added "cat" function so you could see what i is before the function prints out the square root value.
MySqrt <- function (x, eps = 1e-6, iter = 100, verbose = TRUE) {
y = 0
y[1] = as.numeric(readline(prompt="Please enter your initial square root guess: "))
for (i in 1:iter) {
y[i+1] = as.numeric((y[i] + (x/y[i]))/2)
if (i == 100 || abs(y[i+1] - y[i]) < eps) {
cat("This is", i,"th try: \n")
return(y[i+1])
}
}
}
Try this simply:
newton.raphson <- function(x, start, epsilon=0.0001, maxiter=100) {
y <- c(start) # initial guess
a <- 1 # number of iterations
while (TRUE) {
y <- c(y, (y[a] + x / y[a])/2)
if (abs(y[a+1] - y[a]) < epsilon | a > maxiter) { # converged or exceeded maxiter
return(y[a+1])
}
a <- a + 1
}
}
newton.raphson(2, 0.5, 0.01)
# [1] 1.414234
newton.raphson(3, 0.5, 0.01)
# [1] 1.732051
since sqrt(n) < n/2 then with precision of 1/10000
sqrnt=function(y){
x=y/2
while (abs(x*x-y) > 1e-10)
{x=(x+y/x)/2 }
x
}
In Newton’s method. If you want to know the square root of a, you can start estimate a number, x (for examples a/2), you can compute a better estimate with the following formula:
y = (x + a / x) / 2
If y != x, you set x = y, and repeat until y == x. Then you get the square root of a. Please see the code below:
square_root <- function(a) {
x <- a/2
while (TRUE) {
y <- (x + a / x) / 2
if (y == x) break
x <- y
}
return(y)
}

Resources