-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathREADME.Rmd
122 lines (92 loc) · 2.45 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
---
title:
output: github_document
---
```{r setup, echo = FALSE}
knitr::opts_chunk$set(
warning = FALSE,
echo = TRUE,
collapse = TRUE,
message = TRUE,
comment = "#>",
fig.path = "man/figures/README-"
)
```
<!-- badges: start -->
[![R-CMD-check](https://github.com/NicChr/cppdoubles/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/NicChr/cppdoubles/actions/workflows/R-CMD-check.yaml)
[![CRAN status](https://www.r-pkg.org/badges/version/cppdoubles)](https://CRAN.R-project.org/package=cppdoubles)
[![Codecov test coverage](https://codecov.io/gh/NicChr/cppdoubles/graph/badge.svg)](https://app.codecov.io/gh/NicChr/cppdoubles)
<!-- badges: end -->
# cppdoubles
# **Fast Relative Comparisons of Floating Point Numbers in C++**
You can install `cppdoubles` using the below code.
```{r install, message = FALSE, eval = FALSE}
remotes::install_github("NicChr/cppdoubles")
```
Comparing equality of 2 double vectors
```{r basic}
library(cppdoubles)
### Basic usage ###
# Standard equality operator
sqrt(2)^2 == 2
# approximate equality operator
sqrt(2)^2 %~==% 2
```
Other approximate equality operators
```{r}
sqrt(2)^2 %~>=% 2
sqrt(2)^2 %~<=% 2
sqrt(2)^2 %~>% 2
sqrt(2)^2 %~<% 2
# Alternatively
double_equal(2, sqrt(2)^2)
double_gte(2, sqrt(2)^2)
double_lte(2, sqrt(2)^2)
double_gt(2, sqrt(2)^2)
double_lt(2, sqrt(2)^2)
```
All comparisons are vectorised and recycled
```{r}
double_equal(sqrt(1:10),
sqrt(1:5),
tol = c(-Inf, 1e-10, Inf))
```
One can check if a double is a whole number like so
```{r}
# One can check for whole numbers like so
whole_number <- function(x, tol = getOption("cppdoubles.tolerance", sqrt(.Machine$double.eps))){
double_equal(x, round(x), tol = tol)
}
x <- seq(-5, 5, by = 0.2)
whole_nums <- x[whole_number(x)]
whole_nums
```
`all_equal` as an alternative to base R `all.equal.numeric`
```{r}
x <- seq(0, 10, 2)
y <- sqrt(x)^2
all_equal(x, y)
all_equal(x, 1)
all_equal(x, NA)
isTRUE(all_equal(x, NA))
```
Benchmark against `all.equal.numeric`
```{r}
library(bench)
x <- abs(rnorm(10^7))
y <- sqrt(x)^2
z <- x^2
# 2 approximately equal vectors
mean(rel_diff(x, y))
mark(base = isTRUE(all.equal(x, y)),
cppdoubles = all_equal(x, y))
# 2 significantly different vectors
mean(rel_diff(x, z))
mark(base = isTRUE(all.equal(x, z)),
cppdoubles = all_equal(x, z))
```
Benchmark against using absolute differences
```{r}
mark(double_equal(x, y),
abs_diff(x, y) < sqrt(.Machine$double.eps))
```