Creating a function which returns certain value - r

I have this exercise and I cant figure it out.
Create a function ans(x, y, c) which returns the value c*x^2*y, if x^2 <= y <= 1, and the value 0 otherwise. When you are ready input c.
I have 2 different solutions but I can't quite understand how to organize the function correctly. Neither one is correct.
Solution 1)
ans <- function(x,y,c){
if (x^2 <= y && <= 1)
return(c*x^2*y)
}
else{
return(0)
}
Solution 2)
ans <- function(x,y,c){
if (x^2 <= y & y <= 1)
return(c*x^2*y)
else if(x^2 <= 1){
return(c*x^2*y)
}
else{}
return(0)
}

Just check the format of your function. Here may be something you want:
ans <- function(x,y,c){
if (x^2 <= y & y <= 1){
return(c*x^2*y)
}else{return(0)}}

Related

Prime number generator using for loop in R

Trying to create a for loop in which you input a number and the function tells you whether or not the number is prime or not. I used two examples being n1 <- 100 and n2 <- 101.
Here is my code below:
n1 <- 100
n2 <-101
answer = TRUE
for(i in n1){
if (n1 %% (i-1) == 0){
prime1=FALSE
}else {
prime1=TRUE
}
}
prime1
answer = TRUE
for (i in n2){
if (n2 %% (i-1) == 0){
prime2=FALSE
}else {
prime2=TRUE
}
}
prime2
The problem is that the function will generate the same output for both depending on one difference in the code.
In the first "if" statement, both functions will generate output TRUE if I put in the line (i-1). However, if I instead change the line of code to "n1 %% i == 0" as opposed to "n1 %% (i-1) == 0", both functions generate the output FALSE.
Any pointers? Thanks!
Here's a simple prime checker using a for loop.
With n1 <- 100 :
for(i in seq(2, ceiling(sqrt(n1)))) {
if(n1 %% i == 0){
print(FALSE)
break
}
if(i == ceiling(sqrt(n1)))
print(TRUE)
}
#> [1] FALSE
With n2 <- 101
for(i in seq(2, ceiling(sqrt(n2)))) {
if(n2 %% i == 0){
print(FALSE)
break
}
if(i == ceiling(sqrt(n2)))
print(TRUE)
}
#> [1] TRUE

How can you check whether a sequence is an 'almost increasing sequence' in R?

A sequence (e.g. c(1,2,3,4)) is almost increasing when we can remove exactly one element from the sequence and get a strictly increasing sequence (i.e. a0 < a1 < ... < an). I'm trying to find a way to check whether a sequence is almost increasing. If it is, I want to return TRUE; if it isn't I want to output FALSE. I've got this far:
solution <- function(sequence) {
sequence1 <- unlist(sequence)
if (length(sequence1) == 1) {
next
}
count <- 0
for (i in (length(sequence1) - 1)) {
if (sequence1[i + 1] > sequence1[i]) {
next
} else if (((sequence1[i + 2] > sequence1[i]) & count == 0) & i !=
length(sequence1)-1) {
sequence1 <- sequence1[- (i + 1)]
count <- count + 1
} else if ((sequence1[i + 1] > sequence1[i - 1]) & count == 0 & i != 1) {
sequence1 <- sequence1[-i]
count <- count + 1
} else {
return(FALSE)
}
}
return(TRUE)
}
I've used unlist() because codesignal, for some reason, doesn't accept you to refer to the function argument within the function. This works for some sequences: solution(c(4,1,5)) correctly returns TRUE. It doesn't work for others: solution(c(1, 1, 1, 2, 3)) incorrectly returns TRUE. solution(c(2,1,2,1)) correctly returns FALSE and yet solution(c(1,2,1,2)) incorrectly returns TRUE. I've lost my grip on what's going on. I wonder if anyone can spot anything?
Clarification: the basic idea of my code is to iterate through the sequence and for each element check whether its right neighbour is a bigger number. If it isn't, then we have two options: get rid of i or get rid of i+1, so I check those in turn. Since we can only make one change, i've added the condition that if count is 1, then we skip to finish. Also, if the index is 1 then we can't check i-1, and if the index is length(sequence)-1, then we can't check i+2, so i've added those conditions in to make sure my code skips to the other option if appropriate.
Here is a solution which works for me. The idea is that diff(x) has negative elements for every downwards step in x. For example, min(diff(x)) is positive, if x is strictly increasing. If diff(x)[i] <= 0 for exactly one index i, we have to check whether either removing x[i] or removing x[i+1] makes the sequence strictly increasing. The following function passed all tests I tried:
check_almost <- function(x) {
if (length(x) < 2) {
return(TRUE)
}
d <- diff(x)
i <- which(d <= 0)
if (length(i) == 0) {
return(TRUE) # strictly increasing
} else if (length(i) > 1) {
return(FALSE)
}
return(i == 1 || # we can remove x[1]
i == length(d) || # we can remove x[length(x)]
d[i-1]+d[i] > 0 || # we can remove x[i]
d[i] + d[i+1] > 0) # we can remove x[i+1]
}

What's wrong with this function? - R [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 4 years ago.
The function follows:
qual <- function(x, y, z)
{if ((abs(x - y) <= .15)&(abs(x - z) <= .15)&(abs(y - z) <= .15)){print("grade A")}
else if((abs(x - y) <= .15)|(abs(x - z) <= .15)){print("grade B")}
else if((abs(x - y) <= .2)|(abs(x - z) <= .2)){print("grade C")}
else if((abs(x - y) <= .25)|(abs(x - z) <= .25)){print("grade D")}
else {print("check manually")}}
It seems that, e.g., the output of qual(1.19, 1.04, 1.06) and qual(1.10, .95, .97)should be "grade A". However, the output is "grade A" and "grade B", respectively.
Why is this?
I think you are hitting some floating point precision problems. See Why are these numbers not equal for a full explanation.
To fix this, you can use a short function that takes into account minor precision errors when comparing:
less_equal_safe <- function(x, y) {
(x < y) | dplyr::near(x, y)
}
qual <- function(x, y, z) {
if (less_equal_safe(abs(x - y), .15) & (abs(x - z) <= .15) &(abs(y - z) <= .15)) {
print("grade A")
} else if ((abs(x - y) <= .15) | (abs(x - z) <= .15)) {
print("grade B")
} else if ((abs(x - y) <= .2) | (abs(x - z) <= .2)) {
print("grade C")
}
else if ((abs(x - y) <= .25) | (abs(x - z) <= .25)) {
print("grade D")
} else {
print("check manually")
}
}
(note that you need the dplyr package to be installed to use dplyr::near)
I've only replaced the first comparison, which is the one that was causing the issue, but ideally you should replace all comparisons in your function with the float-safe function.

Create sequence in R

Hi I was wondering if someone knows how to realize this sequence in R?
Consider a sequence with following requirement.
a1=1
an=an-1+3 (If n is a even number)
an=2×an-1-5 (If n is a odd number)
e.g. 1,4,3,6,7,10,15,...
a30=?
Try the following.
It will return the entire sequence, not just the last element.
seq_chih_peng <- function(n){
a <- integer(n)
a[1] <- 1
for(i in seq_along(a)[-1]){
if(i %% 2 == 0){
a[i] <- a[i - 1] + 3
}else{
a[i] <- 2*a[i - 1] - 5
}
}
a
}
seq_chih_peng(30)
Note that I do not include code to check for input errors such as passing n = 0 or a negative number.
If you want to do it recursively, you just have the write the equations in your function as follows:
sequence <- function(n) {
if (n == 1) return(1)
else if (n > 1) {
if (n %% 2 == 1) {
return(2 * sequence(n - 1) - 5)
}else{
return(sequence(n - 1) + 3)
}
}else{
stop("n must be stricly positive")
}
}
sequence(30)
# returns 32770

Get distance to next largest floating point number in R [duplicate]

Is there any implementation of functionality in R, such that it is possible to get the next representable floating point number from a given floating point number. This would be similar to the nextafter function in the C standard library. Schemes such as number + .Machine$double.eps don't work in general.
No, but there are two ways you can make it:
Using C
If you want the exact functionality of the nextafter() function, you can write a C function that works as an interface to the function such that the following two constraints are met:
The function does not return a value. All work is accomplished as a "side effect" (changing the values of arguments).
All the arguments are pointers. Even scalars are vectors (of length one) in R.
That function should then be compiled as a shared library:
R CMD SHLIB foo.c
for UNIX-like OSs. The shared library can be called using dyn.load("foo.so"). You can then call the function from inside R using the .C() function
.C("foo", ...)
A more in depth treatment of calling C from R is here.
Using R
number + .Machine$double.eps is the way to go but you have to consider edge cases, such as if x - y < .Machine$double.eps or if x == y. I would write the function like this:
nextafter <- function(x, y){
# Appropriate type checking and bounds checking goes here
delta = y - x
if(x > 0){
factor = 2^floor(log2(x)) + ifelse(x >= 4, 1, 0)
} else if (x < 0) {
factor = 65
}
if (delta > .Machine$double.eps){
return(x + factor * .Machine$double.eps)
} else if (delta < .Machine$double.eps){
return(x - factor * .Machine$double.eps)
} else {
return(x)
}
}
Now, unlike C, if you want to check integers, you can do so in the same function but you need to change the increment based on the type.
UPDATE
The previous code did not perform as expected for numbers larger than 2. There is a factor that needs to be multiplied by the .Machine$double.eps to make it large enough to cause the numbers to be different. It is related to the nearest power of 2 plus one. You can get an idea of how this works with the below code:
n <- -100
factor <- vector('numeric', 100)
for(i in 1:n){
j = 0
while(TRUE){
j = j + 1
if(i - j * .Machine$double.eps != i) break()
}
factor[i] = j
}
If you prefer Rcpp:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
double nextAfter(double x, double y) {
return nextafter(x, y);
}
Then in R:
sprintf("%.20f", 1)
#[1] "1.00000000000000000000"
sprintf("%.20f", nextAfter(1, 2))
#[1] "1.00000000000000022204"
I'm not sure if Christopher Louden's answer works for all values, but here's a pure R version of the classic approach (increments/decrements the integer bits). R does not make it easy to convert between doubles and integers, nor does it have a 64-bit integer type, so there's quite a lot of code for this.
doubleToRaw <- function(d) writeBin(d, raw());
rawToDouble <- function(r) readBin(r, numeric());
int64inc <- function(lo, hi) {
if (lo == 0xffffffff) { hi <- hi + 1; lo <- 0; } else { lo <- lo + 1; }
return(c(lo, hi));
}
int64dec <- function(lo, hi) {
if (lo == 0) { hi <- hi - 1; lo <- 0xffffffff; } else { lo <- lo - 1; }
return(c(lo, hi));
}
nextafter <- function(x, y) {
if (is.nan(x + y))
return(NaN);
if (x == y)
return(x);
if (x == 0)
return(sign(y) * rawToDouble(as.raw(c(0, 0, 0, 0, 0, 0, 0, 1))));
ints <- packBits(rawToBits(doubleToRaw(x)), "integer")
if ((y > x) == (x > 0))
ints <- int64inc(ints[1], ints[2])
else
ints <- int64dec(ints[1], ints[2]);
return(rawToDouble(packBits(intToBits(ints), "raw")))
}

Resources