Using math functions

Mathematical functions are an essential part in all computing environments. R provides several groups of basic math functions.

Basic functions

The basic functions include square root, and exponential and logarithm functions as the following table shows:

Basic functions

Note that sqrt() only works with real numbers. If a negative number is supplied, NaN will be produced:

sqrt(-1)
## Warning in sqrt(-1): NaNs produced
## [1] NaN 

In R, numeric values can be finite, infinite (Inf and -Inf), and NaN values. The following code will produce infinite values.

First, produce a positively infinite value:

1 / 0
## [1] Inf 

Then, produce a negatively infinite value:

log(0)
## [1] -Inf 

There are several test functions to check whether a numeric value is finite, infinite, or NaN:

is.finite(1 / 0)
## [1] FALSE
is.infinite(log(0))
## [1] TRUE 

Using is.infinite(), how can we check whether a numeric value is -Inf? Inequality still works with infinite values in R:

1 / 0 < 0
## [1] FALSE
1 / 0 > 0
## [1] TRUE
log(0) < 0
## [1] TRUE
log(0) > 0
## [1] FALSE 

Therefore, we can test the number with is.infinite() and compare the elements to 0 at the same time:

is.pos.infinite <- function(x) {
  is.infinite(x) & x > 0
}
is.neg.infinite <- function(x) {
  is.infinite(x) & x < 0
}
is.pos.infinite(1/0)
## [1] TRUE
is.neg.infinite(log(0))
## [1] TRUE 

Like sqrt(), if the input value goes beyond the domain of log function, that is, x > 0, then the function returns NaN with a warning:

log(-1)
## Warning in log(-1): NaNs produced
## [1] NaN 

Number rounding functions

The following functions are used to round numbers in different ways:

Symbol

Example

Value

[x] log

ceiling(10.6)

11

[x] log

floor(9.5)

9

truncate

trunc(1.5)

1

round

round(pi,3)

3.142

significant numbers

signif(pi, 3)

3.14

Previously, we showed that using options(digits =) can modify the number of digits to display, but this does not change the actual number of digits to remember. The preceding functions round the numbers and may cause potential loss of information.

For example, if the input number 1.50021 is already precise, then rounding it to 1 digit will result in 1.5 and the other digits (information) are lost. Therefore, you should make sure if the digits to drop are indeed ignorable due to imprecision or noise before performing any rounding.

Trigonometric functions

The following table lists the most commonly used trigonometric functions:

Symbol

Example

Value

sin (x)

sin(0)

0

cos (x)

cos(0)

1

tan (x)

tan(0)

0

arcsin (x)

asin(1)

1.5707963

arcos (x)

acos(1)

0

arctan (x)

atan(1)

0.7853982

R also provides a numeric version of π:

pi
## [1] 3.141593 

In maths, equation sin (π) = 0 strictly holds. However, the same formula does not lead to 0 in R or any other typical numeric computing software due to some precision issues of floating numbers:

sin(pi)
## [1] 1.224606e-16 

To compare numbers with near equality, use all.equal() instead. While sin(pi) == 0 returns FALSEall.equal(sin(pi), 0) returns TRUE with the default tolerance of 1.5e-8.

Another three functions are provided to make it precise when the input is a multiple of π:

Symbol

Example

Value

sin (πx)

sinpi(1)

0

cos (πx)

cospi(0)

1

tan (πx)

tanpi(1)

0

Hyperbolic functions

Similar to other computing software, hyperbolic functions are provided as shown in the following table:

Symbol

Example

Value

sinh (x)

sinh(1)

1.1752012

cosh (x)

cosh(1)

1.5430806

tanh (x)

tanh(1)

0.7615942

arcsinh (x)

asinh(1)

0.8813736

arccosh (x)

acosh(1)

0

arctanh (x)

atanh(0)

0

Extreme functions

It is common to calculate the maximum or minimum values of some numbers. The following table lists and demonstrates the simple use of max() and min():

Symbol

Example

Value

max(...)

max(1, 2, 3)

3

min(...)

min(1, 2, 3)

1

These two functions work not only with multiple scalar arguments but also with a vector input:

max(c(1, 2, 3))
## [1] 3 

Also, they work with multiple vector input:

max(c(1, 2, 3),
    c(2, 1, 2),
    c(1, 3, 4))
## [1] 4
min(c(1, 2, 3),
    c(2, 1, 2),
    c(1, 3, 4))
## [1] 1 

The output demonstrates that max() returns the maximal value among all values of all input vectors and min() returns vice versa.

What if we want to obtain maximal or minimal values of each position among all vectors? Look at the following lines of code:

pmax(c(1, 2, 3),
    c(2, 1, 2),
    c(1, 3, 4))
## [1] 2 3 4 

This basically finds the maximal value among all numbers at position 1, then at position 2, and so on, which has the same output as the following code:

x <- list(c(1, 2, 3),
          c(2, 1, 2),
          c(1, 3, 4))
c(max(x[[1]][[1]], x[[2]][[1]], x[[3]][[1]]),
  max(x[[1]][[2]], x[[2]][[2]], x[[3]][[2]]),
  max(x[[1]][[3]], x[[2]][[3]], x[[3]][[3]]))
## [1] 2 3 4 

This is called the parallel maxima. The twin function pmin() works to find the parallel minima:

pmin(c(1, 2, 3),
     c(2, 1, 2),
     c(1, 3, 4))
## [1] 1 1 2 

These two functions can be very useful to quickly compose a vectorized function with specific functions as floor and/or ceiling. For example, suppose spread() is a piecewise function. If the input is less than -5, the value is -5. If the input is between -5 to 5, the value is input. If the input is greater than 5, then the value is 5.

A naive implementation uses if to branch the pieces:

spread <- function(x) {
  if (x < -5) -5
  else if (x > 5) 5
  else x
} 

The function works with scalar input, but it is not automatically vectorized:

spread(1)
## [1] 1
spread(seq(-8, 8))
## Warning in if (x < -5) -5 else if (x > 5) 5 else x: the
## condition has length > 1 and only the first element will be
## used
## [1] -5 

One method is to use pmin() and pmax(), and the function will be automatically vectorized:

spread2 <- function(x) {
  pmin(5, pmax(-5, x))
}
spread2(seq(-8, 8))
##  [1] -5 -5 -5 -5 -4 -3 -2 -1  0  1  2  3  4  5  5  5  5 

Another method is to use ifelse():

spread3 <- function(x) {
  ifelse(x < -5, -5, ifelse(x > 5, 5, x))
}
spread3(seq(-8, 8))
##  [1] -5 -5 -5 -5 -4 -3 -2 -1  0  1  2  3  4  5  5  5  5 

The previous two functions, spread2() and spread3(), both have the same graphics:

Extreme functions
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset