This is only for strictly monotonically functions that have unique crossing at zero. There are potentially three types of inputs relevant for the bisection root evaluation. Values in each row are parameters for the same nonlinear function, we want to find roots for N nonlinear functions defined by each row. First type of input are these row specific variable values. Second type of inputs are scalars or arrays that are fixed over all rows. Third type of inputs are values that are shifting over bisection iterations. The implementation here assumes that we have lower and upper bound values that are common across all individauls (rows), and that garantee opposing signs.

ff_opti_bisect_pmap_multi(
  df,
  fc_withroot,
  fl_lower_x,
  fl_upper_x,
  ls_svr_df_in_func,
  svr_root_x = "x",
  it_iter_tol = 50,
  fl_zero_tol = 10^-5,
  bl_keep_iter = TRUE,
  st_bisec_prefix = "bisec_",
  st_lower_x = "a",
  st_lower_fx = "fa",
  st_upper_x = "b",
  st_upper_fx = "fb"
)

Arguments

df

dataframe containing all row/individual specific variable information, will append bisection results to datafram

fc_withroot

function with root, the function should have hard-coded in scalars and arrays that would not change over iterations and would not change across individuals

fl_lower_x

float value of common lower bound

fl_upper_x

float value of common upper bound, opposing sign

ls_svr_df_in_func

list of string names variables in df that are inputs for fc_withroot.

svr_root_x

string the x variable name that appears n fc_withroot.

it_iter_tol

integer how many maximum iterations to allow for bisection at most

fl_zero_tol

float at what gap to zero will algorithm stop

bl_keep_iter

whether to keep all iteration results as data columns

st_bisec_prefix

string prefix for all bisection iteration etc results variables

st_lower_x

string variable name component for lower bound x

st_lower_fx

string variable name component for lower bound x evaluated at function

st_upper_x

string variable name component for upper bound x

st_upper_fx

string variable name component for upper bound x evaluated at function

Value

dataframe containing bisection root for each individual/row

Author

Fan Wang, http://fanwangecon.github.io

Examples

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(tibble)
it_N_child_cnt <- 9
ar_intercept = seq(-10, -1, length.out = it_N_child_cnt)
ar_slope = seq(0.1, 1, length.out = it_N_child_cnt)
df_lines <- as_tibble(cbind(ar_intercept, ar_slope)) %>% rowid_to_column(var='ID')
ar_st_col_names = c('ID','fl_int', 'fl_slope')
df_lines <- df_lines %>% rename_all(~c(ar_st_col_names))
fc_withroot_line <- function(fl_int, fl_slope, x){
  return(fl_int + fl_slope*x)
}
fl_lower_x_line <- 0
fl_upper_x_line <- 100000
ls_svr_df_in_func_line <- c('fl_int', 'fl_slope')
svr_root_x_line <- 'x'
fl_zero_tol = 10^-6
df_bisec <- ff_opti_bisect_pmap_multi(df_lines, fc_withroot_line,
                                           fl_lower_x_line, fl_upper_x_line,
                                           ls_svr_df_in_func_line, svr_root_x_line, bl_keep_iter = FALSE)
#> it_cur:1, fl_p_dist2zr:27494.5
#> it_cur:2, fl_p_dist2zr:13744.5
#> it_cur:3, fl_p_dist2zr:6869.5
#> it_cur:4, fl_p_dist2zr:3432
#> it_cur:5, fl_p_dist2zr:1713.25
#> it_cur:6, fl_p_dist2zr:853.875
#> it_cur:7, fl_p_dist2zr:424.1875
#> it_cur:8, fl_p_dist2zr:209.34375
#> it_cur:9, fl_p_dist2zr:101.921875
#> it_cur:10, fl_p_dist2zr:48.2630208333333
#> it_cur:11, fl_p_dist2zr:22.4405381944444
#> it_cur:12, fl_p_dist2zr:9.83213975694444
#> it_cur:13, fl_p_dist2zr:4.24430338541667
#> it_cur:14, fl_p_dist2zr:1.79055447048611
#> it_cur:15, fl_p_dist2zr:0.783148871527778
#> it_cur:16, fl_p_dist2zr:0.419854058159722
#> it_cur:17, fl_p_dist2zr:0.137461344401042
#> it_cur:18, fl_p_dist2zr:0.0981631808810763
#> it_cur:19, fl_p_dist2zr:0.0471479627821184
#> it_cur:20, fl_p_dist2zr:0.0238359239366318
#> it_cur:21, fl_p_dist2zr:0.0155442555745441
#> it_cur:22, fl_p_dist2zr:0.00779639350043383
#> it_cur:23, fl_p_dist2zr:0.00397608015272343
#> it_cur:24, fl_p_dist2zr:0.00209707683987107
#> it_cur:25, fl_p_dist2zr:0.000747521718342902
#> it_cur:26, fl_p_dist2zr:0.000320964389377071
#> it_cur:27, fl_p_dist2zr:0.000268595086203484
#> it_cur:28, fl_p_dist2zr:7.08483987382399e-05
#> it_cur:29, fl_p_dist2zr:4.65694401001255e-05
#> it_cur:30, fl_p_dist2zr:2.71068678960873e-05
#> it_cur:31, fl_p_dist2zr:1.14395386645841e-05
#> it_cur:32, fl_p_dist2zr:6.38038747870063e-06
df_bisec %>% select(-one_of('f_p_t_f_a'))
#> # A tibble: 9 x 9
#>      ID fl_int fl_slope      x           fx bisec_a_32 bisec_b_32  bisec_fa_32
#>   <int>  <dbl>    <dbl>  <dbl>        <dbl>      <dbl>      <dbl>        <dbl>
#> 1     1 -10       0.1   100.   -0.000000689     100.       100.   -0.000000689
#> 2     2  -8.88    0.213  41.8   0.00000268       41.8       41.8  -0.00000227 
#> 3     3  -7.75    0.325  23.8   0.00000372       23.8       23.8  -0.00000385 
#> 4     4  -6.62    0.438  15.1   0.00000242       15.1       15.1  -0.00000776 
#> 5     5  -5.5     0.55   10.0   0.00000346       10.0       10.0  -0.00000934 
#> 6     6  -4.38    0.662   6.60 -0.0000141         6.60       6.60 -0.0000141  
#> 7     7  -3.25    0.775   4.19 -0.00000960        4.19       4.19 -0.00000960 
#> 8     8  -2.12    0.888   2.39 -0.00000506        2.39       2.39 -0.00000506 
#> 9     9  -1       1       1.00 -0.0000157         1.00       1.00 -0.0000157  
#> # ... with 1 more variable: bisec_fb_32 <dbl>