From 8164c2be3b4849a9c77e44b9659a3de8af010bd7 Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Mon, 13 Dec 2021 03:02:58 +0000
Subject: CTAN sync 202112130302

---
 .../latex/contrib/numerica-plus/numerica-plus.sty  | 916 +++++++++++++++++++++
 1 file changed, 916 insertions(+)
 create mode 100644 macros/latex/contrib/numerica-plus/numerica-plus.sty

(limited to 'macros/latex/contrib/numerica-plus/numerica-plus.sty')

diff --git a/macros/latex/contrib/numerica-plus/numerica-plus.sty b/macros/latex/contrib/numerica-plus/numerica-plus.sty
new file mode 100644
index 0000000000..445c2b9ec6
--- /dev/null
+++ b/macros/latex/contrib/numerica-plus/numerica-plus.sty
@@ -0,0 +1,916 @@
+% This is file `numerica-plus.sty'.
+%
+% This work may be distributed and/or modified under the conditions
+% of the LaTeX Project Public License, either version 1.3c of this 
+% license or any later version; see
+% http://www.latex-project.org/lppl.txt
+%
+% Andrew Parsloe (ajparsloe@gmail.com)
+% 
+\RequirePackage{numerica}[2021/12/07]
+\@ifpackagelater{numerica}{2021/12/07}
+  {}
+  {%
+    \PackageError{numerica-plus}{Package numerica too old.}
+      {Please update the package.}
+    \endinput
+  }
+\ProvidesExplFile
+  {numerica-plus.sty}
+  {2021/12/10}
+  {2.0.0}
+  {Iterate functions, find zeros/extrema of functions, evaluate recurrences }
+%----------------------------------------------------------
+\cs_generate_variant:Nn \tl_if_novalue:nTF { o }
+
+\clist_map_inline:nn { iter,solve } 
+  { 
+    \tl_new:c { g__nmc_info_#1_tl } 
+    \tl_gset:cn { g__nmc_info_#1_tl } { 0 }
+  }
+\clist_gput_right:Nn \g__nmc_info_proc_clist { iter, solve }
+
+\cs_new_protected:Npn \__nmc_plus_get_var:NNn #1#2#3
+  { 
+    \tl_if_empty:NT #1
+      { 
+        \tl_set:Nx \l_tmpa_tl 
+            { \seq_item:Nn \l__nmc_vv_all_seq { \g__nmc_consts_vv_int } }
+        \quark_if_no_value:NTF \l_tmpa_tl
+          { 
+            \__nmc_error_where:n { \__nmc_verb:n { #2 } }
+            \__nmc_error_what:n { No~#3~variable~specified~in } }
+          { 
+            \__nmc_vv_split_item:V \l_tmpa_tl
+            \tl_set_eq:NN #1 \l__nmc_eq_var_tl
+          }
+      }
+  }
+%#1 vv-list reversed #2 var_tl #3 \nmc<cmd> #4 {adjective}
+\cs_new_protected:Npn \__nmc_plus_vv_digest:NNNn #1#2#3#4
+  {
+    \clist_push:NV \l_nmc_formula_tl #2
+    \__nmc_vv_digest:N #1 
+    \tl_if_empty:NTF #2
+      { \__nmc_plus_get_var:NNn #2 #3 { #4 } }
+      { \clist_pop:NN \l_nmc_formula_tl #2 }
+  }
+\cs_new_protected:Npn \__nmc_plus_reuse:nNN #1#2#3
+  {
+    \int_case:nnF { #1 }
+      { 
+        { 1 }
+          {
+            \seq_pop:NN #2 \l_tmpa_tl
+            \seq_pop:NN #3 \l_tmpb_tl
+            \tl_gset:Nx \g__nmc_reuse_tl 
+                { { \l_tmpa_tl , \l_tmpb_tl } }
+            \seq_mapthread_function:NNN #2 #3 \__nmc_plus_reuse_display:nn
+          }
+        { 2 }
+          { 
+            \tl_gset:Nx \g__nmc_reuse_tl 
+                { \seq_use:Nn #3 { , } } 
+          }
+      }
+      { \tl_gset_eq:NN \g__nmc_reuse_tl \l_nmc_result_tl }
+  }
+\cs_new_protected:Npn \__nmc_plus_reuse_display:nn #1#2
+  { \clist_gput_right:Nx \g__nmc_reuse_tl { { #1 , #2 } } }
+  
+% \nmcIterate %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\int_new:N \l__nmc_iter_total_int
+\int_new:N \l__nmc_iter_view_int
+\int_new:N \l__nmc_iter_round_int
+\tl_new:N  \l__nmc_iter_var_tl
+\fp_new:N  \l__nmc_iter_first_fp
+\seq_new:N \l__nmc_iter_result_seq
+\seq_new:N \l__nmc_iter_index_seq
+
+\fp_new:N \l__nmc_iter_fixedpti_fp
+\fp_new:N \l__nmc_iter_fixedptii_fp
+
+\tl_new:N \l__nmc_iter_begin_tl
+\tl_new:N \l__nmc_iter_end_tl
+
+\nmc_define:NnN \nmcIterate { iter } \iter
+
+\cs_gset_protected:Npn \__nmc_iter_initialize:
+  {
+    \tl_set:Nn \l__nmc_dbg_idiii_tl { function }
+    \tl_set:Nn \l__nmc_dbg_idv_tl { stored }
+  }
+\cs_gset_protected:Npn \__nmc_iter_settings_digest:
+  {
+    \bool_set_false:N \l__nmc_allow_TF_out_bool
+    \int_set:Nn \l__nmc_iter_total_int 
+        { \int_max:nn { \l__nmc_iter_total_int } { 1 } }
+    \int_set:Nn \l__nmc_iter_view_int 
+        { \int_min:nn { \int_max:nn { \l__nmc_iter_view_int } 
+            { 1 } } { \l__nmc_iter_total_int } }
+  }
+\cs_gset_protected:Npn \__nmc_iter_vv_digest:N #1
+  { 
+    \__nmc_plus_vv_digest:NNNn #1 
+        \l__nmc_iter_var_tl \nmcIterate {iteration} 
+  }
+\cs_gset_protected:Npn \__nmc_iter_process:
+  { 
+    \int_set:Nn \l__nmc_iter_round_int 
+        { \l__nmc_round_int + \l__nmc_iter_extra_int }
+    % first iterate
+    \__nmc_error_where:n { formula }
+    \tl_clear:N \l__nmc_fp_expr_tl
+    \__nmc_fpify:VN \l_nmc_formula_tl \l__nmc_fp_expr_tl
+    \fp_set:Nn \l__nmc_result_fp { \l__nmc_fp_expr_tl }
+    \__nmc_error_fpflag:
+    \bool_if:NF \g__nmc_error_bool
+      { \fp_set_eq:NN \l__nmc_iter_first_fp \l__nmc_result_fp }
+    \bool_if:NF \g__nmc_error_bool
+      {
+        \__nmc_iter_do:
+        \tl_set_eq:NN \l__nmc_fp_expr_tl \l__nmc_fp_exprn_tl
+      }
+    \bool_if:nF { \g__nmc_error_bool || \l__nmc_num_only_bool }
+      { 
+        \__nmc_iter_environ:
+        \__nmc_iter_write:
+      }
+    \int_if_zero:nF \l__nmc_dbg_int
+      { \__nmc_dbg_get_data: }
+  }
+%--------------------------------------
+\cs_new_protected:Npn \__nmc_iter_do:
+  { 
+    \bool_if:NTF \l__nmc_num_only_bool
+      { 
+        \__nmc_iter_fixed_pt:
+        \bool_if:NF \g__nmc_error_bool
+          { 
+            \__nmc_num_format:nNnN { \l__nmc_iter_fixedpti_fp }
+                \l_nmc_result_tl { \l__nmc_round_int } 
+                    \l__nmc_sci_num_out_bool
+            \int_decr:N \l__nmc_iter_total_int
+            \tl_gset:Nx \g__nmc_info_iter_tl 
+              { \int_use:N \l__nmc_iter_total_int }
+          }
+      }
+      { % don't print initial iterations
+        \int_step_function:nnnN { 1 } { 1 }
+            { \l__nmc_iter_total_int - \l__nmc_iter_view_int - 1 }
+                \__nmc_iter_current:n
+        \bool_if:NF \g__nmc_error_bool
+          { % store then print these ones
+            \seq_clear:N \l__nmc_iter_result_seq
+            \int_step_function:nnnN { 1 } { 1 } 
+              { \int_min:nn { \l__nmc_iter_view_int } 
+                  { \l__nmc_iter_total_int - 1 } } \__nmc_iter_current_store:n
+          }
+      }
+  }
+\cs_new_protected:Npn \__nmc_iter_current:n #1
+  { % stepping function
+    \bool_if:NF \g__nmc_error_bool
+      {
+        \__nmc_calc_fn_val:VNnN \l__nmc_iter_var_tl \l_nmc_formula_tl
+            { \l__nmc_result_fp } \l__nmc_result_fp
+      }
+  }
+\cs_new_protected:Npn \__nmc_iter_current_store:n #1
+  { % stepping function
+    \__nmc_calc_fn_val:VNnN \l__nmc_iter_var_tl \l_nmc_formula_tl 
+        { \l__nmc_result_fp } \l__nmc_result_fp
+    \bool_if:NF \g__nmc_error_bool
+      {
+        \__nmc_num_format:nNnN { \l__nmc_result_fp } \l_nmc_result_tl
+             { \l__nmc_round_int } \l__nmc_sci_num_out_bool 
+        \seq_put_right:NV \l__nmc_iter_result_seq \l_nmc_result_tl
+        \int_set:Nn \l_tmpa_int
+            { \l__nmc_iter_total_int - \l__nmc_iter_view_int + #1 }
+        \seq_put_right:Nx \l__nmc_iter_index_seq { \int_use:N \l_tmpa_int }
+      }
+  }
+\cs_new_protected:Npn \__nmc_iter_fixed_pt:
+  { % already 1 iteration
+    \int_set:Nn \l__nmc_iter_total_int { 1 }
+    \fp_set_eq:NN \l__nmc_iter_fixedpti_fp \l__nmc_iter_first_fp
+    \fp_set:Nn \l__nmc_iter_fixedptii_fp { \l__nmc_iter_fixedpti_fp + 1 }
+    \bool_until_do:nn
+        { 
+          \fp_compare_p:nNn { 0 } = 
+              { round( \l__nmc_iter_fixedpti_fp - \l__nmc_iter_fixedptii_fp,
+                  \l__nmc_iter_round_int ) }
+          || \g__nmc_error_bool
+        }
+      {
+        \int_incr:N \l__nmc_iter_total_int
+        \fp_set_eq:NN \l__nmc_iter_fixedptii_fp \l__nmc_iter_fixedpti_fp
+        \__nmc_calc_fn_val:VNnN \l__nmc_iter_var_tl \l_nmc_formula_tl
+            { \l__nmc_result_fp } \l__nmc_result_fp
+        \fp_set_eq:NN \l__nmc_iter_fixedpti_fp \l__nmc_result_fp
+        \int_compare:nNnF { \l__nmc_iter_total_int } < 
+              { \l__nmc_iter_max_int }
+          {
+            \bool_gset_true:N \g__nmc_error_bool
+            \__nmc_error_what:n 
+                { 
+                  No~fixed~point~attained~after~$\int_use:N 
+                  \l__nmc_iter_total_int$~iterations~of 
+                }
+          }
+      }
+  }
+\cs_new_protected:Npn \__nmc_iter_environ:
+  {
+    \tl_set:Nx \l__nmc_iter_begin_tl 
+        { 
+          \mode_if_math:F { \exp_not:o \l__nmc_math_delimi_tl } 
+          \exp_not:N \begin{array}{r@{}l} 
+          \bool_if:NTF \l__nmc_wraps_math_bool
+            { \exp_not:o \l__nmc_formula_dup_tl &{}= }
+            { &{} }
+        }
+    \tl_set:Nx \l__nmc_iter_end_tl 
+        { 
+          \exp_not:N \end{array}
+          \mode_if_math:F { \exp_not:o \l__nmc_math_delimii_tl } 
+        }
+  }
+\cs_new_protected:Npn \__nmc_iter_write:
+  { 
+    \__nmc_num_format:nNnN { \l__nmc_iter_first_fp } \l_tmpa_tl
+         { \l__nmc_round_int } \l__nmc_sci_num_out_bool
+    \tl_gset:Nx \g__nmc_info_iter_tl { \int_use:N \l__nmc_iter_total_int }
+    \__nmc_if_mod_zero:nnTF { \l__nmc_dbg_int } { 7 }
+      { \seq_get_right:NN \l__nmc_iter_result_seq \l_nmc_result_tl }
+      {
+        \tl_set:Nx \l_nmc_result_tl 
+          {
+            \exp_not:o \l__nmc_iter_begin_tl
+            \l_tmpa_tl 
+            \exp_not:o \l__nmc_vv_display_tl
+            \int_compare:nNnT 
+                { \l__nmc_iter_total_int } > { \l__nmc_iter_view_int + 1 }
+              {
+                \\ & \exp_not:N \ldots
+                \ \exp_not:N\mbox{final\ 
+                \int_use:N \l__nmc_iter_view_int\ of\ \g__nmc_info_iter_tl :}
+              }
+            \int_compare:nNnT { \l__nmc_iter_total_int } > { 1 }
+              { \\ & \exp_not:N \hookrightarrow }
+            \seq_use:Nn \l__nmc_iter_result_seq { \\ & \hookrightarrow } 
+            \exp_not:o \l__nmc_iter_end_tl
+          }
+        }
+  }
+\cs_gset_protected:Npn \__nmc_iter_display:
+  { 
+    \bool_if:NTF \l__nmc_num_only_bool
+      { \tl_gset_eq:NN \g__nmc_reuse_tl \l_nmc_result_tl }
+      {
+        \__nmc_plus_reuse:nNN { \l__nmc_iter_reuse_int }
+            \l__nmc_iter_index_seq \l__nmc_iter_result_seq
+      }
+    \l_nmc_result_tl
+  }
+%--------------------------------------
+%\nmcSolve
+\int_new:N \l__nmc_solve_round_int
+\int_new:N \l__nmc_solve_steps_int
+\int_new:N \l__nmc_solve_slope_int
+\int_new:N \l__nmc_solve_slopei_int 
+\int_new:N \l__nmc_solve_signs_int
+\fp_new:N \l__nmc_solvea_fp
+\fp_new:N \l__nmc_solveb_fp
+\fp_new:N \l__nmc_solvec_fp
+\fp_new:N \l__nmc_solved_fp
+
+\fp_new:N \l__nmc_solvefa_fp
+\fp_new:N \l__nmc_solvefb_fp
+\fp_new:N \l__nmc_solvefc_fp
+\bool_new:N \l__nmc_solve_stop_bool
+
+\nmc_define:NnN \nmcSolve { solve } \solve
+
+\cs_gset_protected:Npn \__nmc_solve_initialize:
+  {
+    \tl_set:Nn \l__nmc_dbg_idiii_tl { function }
+    \tl_set:Nn \l__nmc_dbg_idv_tl { stored }
+  }
+\cs_gset_protected:Npn \__nmc_solve_settings_digest: 
+  {
+    \bool_set_false:N \l__nmc_allow_TF_out_bool
+    \tl_if_empty:NF \l__nmc_solve_step_tl
+      { 
+        \__nmc_fpify_set:NV \l__nmc_solve_step_fp \l__nmc_solve_step_tl 
+        \fp_compare:nNnT \l__nmc_solve_step_fp = { 0 }
+          { \__nmc_error_what:n { Non-zero~initial~step~required~in } }
+      } 
+  }
+\cs_gset_protected:Npn \__nmc_solve_vv_digest:N #1
+  { 
+    \__nmc_plus_vv_digest:NNNn #1 
+        \l__nmc_solve_var_tl \nmcSolve {equation} 
+  }
+\cs_gset_protected:Npn \__nmc_solve_process:
+  { 
+    \int_set:Nn \l__nmc_solve_round_int 
+        { \l__nmc_round_int + \l__nmc_solve_extra_int }
+    \bool_if:NF \g__nmc_error_bool
+      { \__nmc_solve_get_trial_vals: }
+    \bool_if:NF \g__nmc_error_bool
+      {
+        \__nmc_error_where:n { function }
+        \__nmc_solve_do:
+      }
+    \bool_if:NF \g__nmc_error_bool
+      { 
+        \__nmc_num_format:nNnN { \l__nmc_solvea_fp } \l_nmc_result_tl
+            { \l__nmc_round_int } \l__nmc_sci_num_out_bool
+        \tl_gset:Nx \g__nmc_info_solve_tl 
+          { \clist_use:Nn \g__nmc_info_solve_tl { + } }
+        \tl_set_eq:NN \l__nmc_fp_expr_tl \l__nmc_fp_exprn_tl
+      }
+    \int_if_zero:nF \l__nmc_dbg_int
+      { \__nmc_dbg_get_data: }  
+  }
+\cs_new_protected:Npn \__nmc_solve_get_trial_vals:
+  {
+    \prop_get:NVN \l__nmc_subst_var_prop 
+        \l__nmc_solve_var_tl \l__nmc_subst_tl
+    % ensure a < b
+    \int_case:nn { \fp_sign:n { \l__nmc_solve_step_fp } }
+      { 
+        { 1 } 
+          { 
+            \fp_set:Nn \l__nmc_solvea_fp { \l__nmc_subst_tl }
+            \fp_set:Nn \l__nmc_solveb_fp 
+                  { \l__nmc_solvea_fp + \l__nmc_solve_step_fp }
+          }
+        { -1 } 
+          { 
+            \fp_set:Nn \l__nmc_solveb_fp { \l__nmc_subst_tl }
+            \fp_set:Nn \l__nmc_solvea_fp 
+                  { \l__nmc_solveb_fp + \l__nmc_solve_step_fp }
+          }
+      }
+  }
+% find opp. signs, zero, or fn min.
+% a b = var vals; fa fb = fn vals
+\cs_new_protected:Npn \__nmc_solve_do:
+  { 
+    \__nmc_solve_calc_values:
+    \int_zero:N \l__nmc_solve_steps_int
+    \tl_gclear:N \g__nmc_info_solve_tl
+    \bool_do_until:nn 
+        {
+          \g__nmc_error_bool || \l__nmc_solve_stop_bool
+          || \int_compare_p:nNn 
+              { \l__nmc_solve_steps_int } > { \l__nmc_solve_max_int } 
+          || \fp_compare_p:nNn { 0 } = 
+                  { round(\l__nmc_solveb_fp - \l__nmc_solvea_fp, 
+                      \l__nmc_solve_round_int) }
+        }
+      {
+        \int_incr:N \l__nmc_solve_steps_int
+        \int_case:nn { \l__nmc_solve_signs_int }
+          {
+            { 0 }  { \__nmc_solve_do_bingo: }
+            { -1 } { \__nmc_solve_do_bisect: }
+            { 1 }  { \__nmc_solve_do_slope: }
+          }
+      }
+    \bool_if:nF { \g__nmc_error_bool || \l__nmc_solve_stop_bool }
+      {
+        \__nmc_error_where:n { $\l_nmc_formula_tl$ }
+        \__nmc_error_what:n 
+            { 
+              No~zero/extremum~found~after~$\int_use:N 
+              \l__nmc_solve_max_int$~steps~for~function 
+            }
+      } 
+  }
+\cs_new_protected:Npn \__nmc_solve_do_bingo:
+  { % fn = 0 to 16 figures
+    \fp_compare:nNnTF { \l__nmc_solvefb_fp } = { 0 }
+      { 
+        \fp_set_eq:NN \l__nmc_solvea_fp \l__nmc_solveb_fp
+        \fp_set_eq:NN \l__nmc_solvefa_fp \l__nmc_solvefb_fp
+      }
+      {
+        \fp_set_eq:NN \l__nmc_solveb_fp \l__nmc_solvea_fp
+        \fp_set_eq:NN \l__nmc_solvefb_fp \l__nmc_solvefa_fp
+      }
+    \bool_set_true:N \l__nmc_solve_stop_bool
+  }
+\cs_new_protected:Npn \__nmc_solve_do_bisect:
+  { 
+    \tl_gset:Nx \g__nmc_info_solve_tl { \int_use:N \l__nmc_solve_steps_int }
+    \int_zero:N \l__nmc_solve_steps_int
+    \fp_set:Nn \l__nmc_solvec_fp { ( \l__nmc_solvea_fp + \l__nmc_solveb_fp ) / 2 }
+    \__nmc_calc_fn_val:VNnN \l__nmc_solve_var_tl \l_nmc_formula_tl 
+        { \l__nmc_solvec_fp } \l__nmc_solvefc_fp 
+    \fp_set:Nn \l__nmc_solved_fp { \l__nmc_solvec_fp + 1 }
+    \bool_until_do:nn
+        { 
+          \g__nmc_error_bool ||
+          \fp_compare_p:nNn { 0 } =
+              { round( \l__nmc_solvec_fp - \l__nmc_solved_fp ,
+                  \l__nmc_solve_round_int ) }
+        }
+      { 
+        \int_incr:N \l__nmc_solve_steps_int
+        \fp_set_eq:NN \l__nmc_solved_fp \l__nmc_solvec_fp
+        \fp_compare:nNnTF { 0 } = { \l__nmc_solvefc_fp }
+          { 
+            \fp_set_eq:NN \l__nmc_solvea_fp \l__nmc_solvec_fp 
+            \fp_set_eq:NN \l__nmc_solvefa_fp \l__nmc_solvefc_fp
+          }
+          {
+            \fp_compare:nNnTF 
+                { sign(\l__nmc_solvefa_fp)sign(\l__nmc_solvefc_fp) } = { 1 }
+              { 
+                \fp_set_eq:NN \l__nmc_solvea_fp \l__nmc_solvec_fp 
+                \fp_set_eq:NN \l__nmc_solvefa_fp \l__nmc_solvefc_fp
+              }
+              { 
+                \fp_set_eq:NN \l__nmc_solveb_fp \l__nmc_solvec_fp 
+                \fp_set_eq:NN \l__nmc_solvefb_fp \l__nmc_solvefc_fp
+              }
+            \fp_set:Nn \l__nmc_solvec_fp 
+                { ( \l__nmc_solvea_fp + \l__nmc_solveb_fp ) / 2 }
+            \__nmc_calc_fn_val:VNnN \l__nmc_solve_var_tl 
+                \l_nmc_formula_tl { \l__nmc_solvec_fp } \l__nmc_solvefc_fp 
+          }
+      }
+    \bool_set_true:N \l__nmc_solve_stop_bool
+    \clist_gput_right:Nx \g__nmc_info_solve_tl { \int_use:N \l__nmc_solve_steps_int }
+  }
+\cs_new_protected:Npn \__nmc_solve_do_slope:
+  {
+    \bool_if:NF \g__nmc_error_bool
+      {
+        \int_if_zero:nTF { \l__nmc_solve_slope_int }
+          { % contract
+            \fp_add:Nn \l__nmc_solvea_fp 
+                { ( \l__nmc_solveb_fp - \l__nmc_solvea_fp ) / 4 }
+            \fp_sub:Nn \l__nmc_solveb_fp 
+                { ( \l__nmc_solveb_fp - \l__nmc_solvea_fp ) / 4 }
+          }
+          { % always towards x-axis
+            \fp_compare:nNnTF { 0 } <
+                { \l__nmc_solvefa_fp * \l__nmc_solve_slope_int }
+              { \__nmc_solve_do_slope_left: }
+              { \__nmc_solve_do_slope_right: }
+          }
+        \fp_set_eq:NN \l__nmc_solved_fp \l__nmc_solvea_fp
+        \int_set_eq:NN \l__nmc_solve_slopei_int \l__nmc_solve_slope_int
+        \__nmc_solve_calc_values:
+      }
+    \bool_if:NF \g__nmc_error_bool
+      {
+        \int_compare:nNnF { \l__nmc_solve_slope_int } = 
+            { \l__nmc_solve_slopei_int }
+          { 
+            \fp_set:Nn \l__nmc_solvec_fp { ( \l__nmc_solvea_fp + \l__nmc_solveb_fp ) / 2 }
+            \int_case:nn { \l__nmc_solve_slopei_int }
+              {
+                { 1 }  { \fp_set_eq:NN \l__nmc_solvea_fp \l__nmc_solvec_fp }
+                { -1 } { \fp_set_eq:NN \l__nmc_solveb_fp \l__nmc_solvec_fp }
+              }
+            \__nmc_solve_calc_values:
+          }
+      }
+    \fp_compare:nNnT { 0 } = 
+        { round(\l__nmc_solveb_fp - \l__nmc_solvea_fp,
+            \l__nmc_solve_round_int) }
+      { \bool_set_true:N \l__nmc_solve_stop_bool }
+  }
+\cs_new_protected:Npn \__nmc_solve_do_slope_left:
+  {
+    \fp_set:Nn \l__nmc_solvec_fp { 2 \l__nmc_solvea_fp - \l__nmc_solveb_fp }
+    \fp_set_eq:NN \l__nmc_solveb_fp \l__nmc_solvea_fp
+    \fp_set_eq:NN \l__nmc_solvea_fp \l__nmc_solvec_fp
+  }
+\cs_new_protected:Npn \__nmc_solve_do_slope_right:
+  {
+    \fp_set:Nn \l__nmc_solvec_fp { 2 \l__nmc_solveb_fp - \l__nmc_solvea_fp }
+    \fp_set_eq:NN \l__nmc_solvea_fp \l__nmc_solveb_fp
+    \fp_set_eq:NN \l__nmc_solveb_fp \l__nmc_solvec_fp
+  }
+\cs_new_protected:Npn \__nmc_solve_calc_values:
+  {
+    \__nmc_calc_fn_val:VNnN \l__nmc_solve_var_tl \l_nmc_formula_tl 
+        { \l__nmc_solvea_fp } \l__nmc_solvefa_fp 
+    \bool_if:NF \g__nmc_error_bool
+      {
+        \__nmc_calc_fn_val:VNnN \l__nmc_solve_var_tl \l_nmc_formula_tl 
+            { \l__nmc_solveb_fp } \l__nmc_solvefb_fp 
+      }
+    \bool_if:NF \g__nmc_error_bool
+      { 
+        \int_set:Nn \l__nmc_solve_slope_int 
+          { \fp_eval:n { sign(\l__nmc_solvefb_fp - \l__nmc_solvefa_fp) } }
+        \int_set:Nn \l__nmc_solve_signs_int 
+          { \fp_eval:n { sign(\l__nmc_solvefa_fp) sign(\l__nmc_solvefb_fp) } }
+      }
+  }
+\cs_gset_protected:Npn \__nmc_solve_display:
+  { 
+    \tl_gset_eq:NN \g__nmc_reuse_tl \l_nmc_result_tl
+    \bool_if:NF \l__nmc_num_only_bool
+      { 
+        \__nmc_num_format:nNnN { \l__nmc_solvefa_fp } \l_tmpa_tl
+             { \l__nmc_round_int } \l__nmc_sci_num_out_bool
+        \tl_set:Nx \l_nmc_result_tl
+            { 
+              \exp_not:o \l__nmc_math_delimi_tl
+              \bool_if:NTF \l__nmc_wraps_math_bool
+                { 
+                  \exp_not:o \l_nmc_formula_tl = \l_tmpa_tl
+                  \bool_if:NTF \l__nmc_vv_multline_bool
+                    { \exp_not:o \l__nmc_vv_display_tl }
+                    { 
+                     \mathchoice{ \exp_not:o \l__nmc_vv_display_tl }
+                          { \exp_not:o \l__nmc_vv_inline_tl }{}{} 
+                    }
+                  \rightarrow \exp_not:N \quad 
+                  \l__nmc_solve_var_tl = \l_nmc_result_tl
+                }
+                {                
+                  \l__nmc_solve_var_tl = \l_nmc_result_tl 
+                  \mathchoice{ \exp_not:o \l__nmc_vv_display_tl }
+                      { \exp_not:o \l__nmc_vv_inline_tl }{}{}
+                }
+              \l__nmc_punc_tl
+              \exp_not:o \l__nmc_math_delimii_tl
+            }
+        \int_if_zero:nT { \l__nmc_solve_reuse_int }
+          { \tl_gset_eq:NN \g__nmc_reuse_tl \l_nmc_result_tl }
+      }
+    \l_nmc_result_tl
+  }
+%--------------------------------------
+% \nmcRecur
+\bool_new:N \l__nmc_recur_ellipsis_bool
+\int_new:N \l__nmc_recur_last_int
+\fp_new:N  \l__nmc_recur_result_fp
+
+\int_new:N \l__nmc_recur_subscr_ini_int
+\int_new:N \l__nmc_recur_subscr_val_int
+\int_new:N \l__nmc_recur_order_int
+\int_new:N \l__nmc_recur_var_int
+
+\tl_new:N \l__nmc_recurrence_tl
+\tl_new:N \l__nmc_recur_base_var_tl
+\tl_new:N \l__nmc_recur_subscr_var_tl
+
+\seq_new:N \l__nmc_recur_result_seq
+\seq_new:N \l__nmc_recur_vars_seq
+
+\nmc_define:NnN \nmcRecur { recur } \recur
+
+\cs_gset_protected:Npn \__nmc_recur_initialize:
+  {
+    \tl_set:Nn \l__nmc_dbg_idiii_tl { relation }
+    \tl_set:Nn \l__nmc_dbg_idv_tl { stored }
+  }
+\cs_gset_protected:Npn \__nmc_recur_settings_digest:
+  { 
+    \bool_set_false:N \l__nmc_allow_TF_out_bool
+    \int_set:Nn \l__nmc_recur_total_int 
+        { \int_max:nn { \l__nmc_recur_total_int } { 1 } }
+    \int_set:Nn \l__nmc_recur_last_int
+        { \int_max:nn { 0 } { \int_min:nn
+             { \l__nmc_recur_last_int } { \l__nmc_recur_total_int } } }
+    \int_set:Nn \l__nmc_recur_first_int
+        { \int_max:nn { 0 } { \int_min:nn { \l__nmc_recur_first_int }
+             { \l__nmc_recur_total_int - \l__nmc_recur_last_int } } }
+    \int_if_zero:nT { \l__nmc_recur_first_int }
+      { \int_decr:N \l__nmc_recur_first_int }
+  }
+\cs_gset_protected:Npn \__nmc_recur_vv_digest:N #1
+  { % #1 = reversed vv clist
+    \bool_set_true:N \l__nmc_multitok_bool
+    \__nmc_recur_elements:
+    \__nmc_recur_vars_change:N #1
+    \__nmc_vv_digest:N #1
+    \__nmc_recur_vv_post:
+    \tl_set_eq:NN \l_nmc_formula_tl \l__nmc_recurrence_tl
+    \int_if_zero:nF \l__nmc_dbg_int
+      { \__nmc_dbg_get_data: }
+  }
+% \l__nmc_recurrence_tl, \l__nmc_recur_base_var_tl,
+% \l__nmc_recur_subscr_var_tl, \l__nmc_recur_subscr_val_int
+\cs_new_protected:Npn \__nmc_recur_elements:
+  {
+    \tl_clear:N \l_tmpa_tl
+    \bool_set_false:N \l_tmpa_bool
+    \tl_map_inline:Nn \l_nmc_formula_tl
+      {
+        \bool_if:NTF \l_tmpa_bool
+          { 
+            \tl_set:Nn \l_tmpa_tl { ##1 } 
+            \tl_map_break:
+          }
+          {
+            \token_if_math_subscript:NTF ##1
+              { 
+                \tl_set:NV \l__nmc_recur_base_var_tl \l_tmpa_tl 
+                \bool_set_true:N \l_tmpa_bool
+              }
+              { \tl_put_right:Nn \l_tmpa_tl { ##1 } }
+          }
+      }
+    \__nmc_recur_parse_subscr:N \l_tmpa_tl
+    \exp_last_unbraced:NV\__nmc_split_eq:w \l_nmc_formula_tl \q_stop
+    \tl_set:NV \l__nmc_recurrence_tl \l__nmc_eq_val_tl
+     \tl_set_rescan:Nno \l__nmc_recurrence_tl { \ExplSyntaxOn } \l__nmc_recurrence_tl
+  }
+\cs_new_protected:Npn \__nmc_recur_parse_subscr:N #1
+  {
+    \tl_clear:N \l__nmc_recur_subscr_var_tl
+    \tl_set:Nn \l_tmpb_tl { 0 }
+    \int_zero:N \l__nmc_recur_subscr_val_int
+    \bool_set_false:N \l_tmpa_bool
+    \tl_map_inline:Nn #1
+      {
+        \bool_if:NTF \l_tmpa_bool
+          { \tl_put_right:Nn \l_tmpb_tl { ##1 } }
+          {
+            \tl_if_in:nnTF { +- } { ##1 }
+              { 
+                \tl_put_right:Nn \l_tmpb_tl { ##1 }
+                \bool_set_true:N \l_tmpa_bool
+              }
+              { \tl_put_right:Nn \l__nmc_recur_subscr_var_tl { ##1 } }
+          }
+      }
+    \int_set:Nn \l__nmc_recur_subscr_val_int { \l_tmpb_tl }
+  }
+\cs_new_protected:Npn \__nmc_recur_vars_change:N #1
+  { % f_{1} etc ==> f_{n-1} etc in #1 (reverse order vv-list)
+    \clist_reverse:N #1
+    \int_zero:N \l__nmc_recur_order_int
+    \clist_clear:N \l_tmpa_clist % --> \l__nmc_recur_vars_seq
+    \clist_clear:N \l_tmpb_clist % --> #1
+    \int_set:Nn \l_tmpb_int { \l__nmc_recur_subscr_val_int - 1 }
+    \tl_set_rescan:Nno #1 { \ExplSyntaxOn } #1 
+    \clist_map_inline:Nn #1
+      {
+        \seq_set_split:Nnn \l_tmpa_seq {_} { ##1 }
+        \seq_pop:NN \l_tmpa_seq \l_tmpa_tl
+        \seq_if_empty:NTF \l_tmpa_seq
+          { \clist_put_left:NV \l_tmpb_clist \l_tmpa_tl }
+          {
+            \tl_if_eq:NNTF \l_tmpa_tl \l__nmc_recur_base_var_tl
+              { % change e.g. f_{1}(x) to f_{n-1}(x)
+                \int_incr:N \l__nmc_recur_order_int
+                \tl_put_right:Nn \l_tmpa_tl { _ }
+                \tl_set_eq:NN \l_tmpb_tl \l__nmc_recur_subscr_var_tl
+                \int_case:nn { \int_sign:n { \l_tmpb_int } }
+                  { 
+                    { -1 } 
+                      { 
+                        \tl_put_right:Nx \l_tmpb_tl 
+                            { \int_use:N \l_tmpb_int }
+                      }
+                    { 0 } { \prg_do_nothing: }
+                    { 1 } 
+                      { 
+                        \tl_put_right:Nn \l_tmpb_tl { + }
+                        \tl_put_right:Nx \l_tmpb_tl 
+                            { \int_use:N \l_tmpb_int } 
+                      }
+                  }
+                \tl_put_right:Nx \l_tmpa_tl { { \l_tmpb_tl } }
+                \int_decr:N \l_tmpb_int
+                \seq_pop:NN \l_tmpa_seq \l_tmpb_tl
+                \int_set:Nn \l__nmc_recur_subscr_ini_int 
+                    { \tl_head:N \l_tmpb_tl }
+                \tl_put_right:Nx \l_tmpa_tl 
+                    { \tl_range:Nnn \l_tmpb_tl { 2 } { -1 } }
+                \clist_put_left:NV \l_tmpb_clist \l_tmpa_tl
+                \seq_set_split:NnV \l_tmpb_seq { = } \l_tmpa_tl
+                \seq_pop:NN \l_tmpb_seq \l_tmpa_tl
+                \clist_put_left:NV \l_tmpa_clist \l_tmpa_tl
+              }
+              { \clist_put_left:Nn \l_tmpb_clist { ##1 } }
+          }
+      }
+    \int_set:Nn \l__nmc_recur_var_int 
+        { \l__nmc_recur_subscr_ini_int + \l__nmc_recur_order_int
+            - \l__nmc_recur_subscr_val_int  }
+    \clist_set_eq:NN #1 \l_tmpb_clist
+    \clist_put_left:NV \l_tmpa_clist \l__nmc_recur_subscr_var_tl
+    \clist_concat:NNN \l_nmc_formula_tl \l__nmc_recurrence_tl \l_tmpa_clist
+  }
+\cs_new_protected:Npn \__nmc_recur_vv_post:
+  {
+    \clist_pop:NN \l_nmc_formula_tl \l__nmc_recurrence_tl
+    \clist_pop:NN \l_nmc_formula_tl \l__nmc_recur_subscr_var_tl
+    \tl_set:Nx \l_tmpa_tl { \int_use:N \l__nmc_recur_var_int }
+    \__nmc_vv_record:NVN \l__nmc_recur_subscr_var_tl \l_tmpa_tl \c_empty_prop
+    \tl_set_eq:NN \l_tmpa_tl \l__nmc_recur_subscr_var_tl
+    \tl_put_right:Nn \l_tmpa_tl { =0 } % formal value
+    \seq_put_left:NV \l__nmc_calc_fn_seq \l_tmpa_tl
+    \seq_set_from_clist:NN \l__nmc_recur_vars_seq \l_nmc_formula_tl
+  }
+%%%%%%%%%%%%%%%%%%%
+\cs_gset_protected:Npn \__nmc_recur_process:
+  { % store initial vals; generate later vals
+    \__nmc_recur_store_ini:
+    \__nmc_error_where:n { recurrence~formula }
+    \__nmc_recur_generate:
+    \seq_get_right:NN \l__nmc_recur_result_seq \l_nmc_result_tl
+    \tl_set_eq:NN \l__nmc_fp_expr_tl \l__nmc_fp_exprn_tl
+  }
+\cs_new_protected:Npn \__nmc_recur_store_ini:
+  {
+    \seq_set_eq:NN \l_tmpa_seq \l__nmc_recur_vars_seq
+    \int_step_inline:nnnn { 1 } { 1 } { \l__nmc_recur_order_int } 
+      {
+        \seq_pop:NN \l_tmpa_seq \l_tmpa_tl
+        \prop_get:NVN \l__nmc_subst_var_prop \l_tmpa_tl \l__nmc_subst_tl
+        \__nmc_num_format:nNnN { \l__nmc_subst_tl } \l_tmpa_tl 
+            { \l__nmc_round_int } \l__nmc_sci_num_out_bool
+        \seq_put_right:NV \l__nmc_recur_result_seq \l_tmpa_tl
+        \tl_set:Nx \l_tmpb_tl { \int_eval:n 
+            { \l__nmc_recur_subscr_ini_int + ##1 -1 } }
+      }
+  }
+\cs_new_protected:Npn \__nmc_recur_generate:
+  {
+    \prop_get:NVN \l__nmc_subst_var_prop 
+        \l__nmc_recur_subscr_var_tl \l__nmc_subst_tl
+    \int_set:Nn \l__nmc_recur_var_int { \l__nmc_subst_tl }
+    \int_set:Nn \l_tmpa_int { \l__nmc_recur_var_int +
+        \l__nmc_recur_total_int - \l__nmc_recur_order_int - 1 }
+    \__nmc_error_where:n { recurrence~relation }
+    \__nmc_if_mod_zero:nnT { \l__nmc_dbg_int } { 7 }
+      { \__nmc_fpify:VN \l__nmc_recurrence_tl \l__nmc_fp_expr_tl }
+    \int_step_function:nnnN { \l__nmc_recur_var_int } { 1 }
+         {\l_tmpa_int } \__nmc_recur_generate_loop:n
+  }
+\cs_new_protected:Npn \__nmc_recur_generate_loop:n #1
+  { 
+    \bool_if:NF \g__nmc_error_bool
+      { % calc. the next term
+        \fp_set:Nn \l_tmpa_fp { #1 }
+        \__nmc_calc_fn_val:VNnN \l__nmc_recur_subscr_var_tl
+            \l__nmc_recurrence_tl { \l_tmpa_fp } \l__nmc_recur_result_fp
+      }
+    \bool_if:NF \g__nmc_error_bool
+      { % store the result
+        \__nmc_num_format:nNnN { \l__nmc_recur_result_fp } 
+            \l_tmpa_tl { \l__nmc_round_int } \l__nmc_sci_num_out_bool
+        \seq_put_right:NV \l__nmc_recur_result_seq \l_tmpa_tl
+        % shift vals "down variable"; tmpa above, tmpb below
+        \seq_set_eq:NN \l_tmpa_seq \l__nmc_recur_vars_seq
+        \seq_pop:NN \l_tmpa_seq \l_tmpb_tl % low var
+        \int_step_inline:nnnn {2} { 1 } { \l__nmc_recur_order_int }
+          {
+            \seq_pop:NN \l_tmpa_seq \l_tmpa_tl % hi var
+            \prop_get:NVN \l__nmc_subst_var_prop \l_tmpa_tl \l__nmc_subst_tl
+            \prop_put:NVV \l__nmc_subst_var_prop \l_tmpb_tl \l__nmc_subst_tl
+            \prop_put:NVV \l__nmc_vv_change_prop \l_tmpb_tl \l__nmc_subst_tl
+            \tl_set_eq:NN \l_tmpb_tl \l_tmpa_tl
+          }
+          % use tmpb, not tmpa, in case order = 1
+          \prop_put:NVx \l__nmc_subst_var_prop \l_tmpb_tl
+              { \fp_use:N \l__nmc_recur_result_fp }
+          \prop_put:NVx \l__nmc_vv_change_prop \l_tmpb_tl
+              { \fp_use:N \l__nmc_recur_result_fp }
+      }
+  }
+\cs_gset_protected:Npn \__nmc_recur_display:
+  { 
+    \bool_if:NTF \l__nmc_num_only_bool
+      { \tl_gset_eq:NN \g__nmc_reuse_tl \l_nmc_result_tl }
+      { 
+        \seq_clear:N \l_tmpa_seq
+        \seq_clear:N \l_tmpb_seq
+        \seq_clear:N \l_tmpc_seq
+        \__nmc_recur_result:NN \l_tmpa_seq \l_tmpb_seq
+        \tl_set:Nx \l_nmc_result_tl
+            { 
+              \exp_not:o \l__nmc_math_delimi_tl
+              \bool_if:NT \l__nmc_wraps_math_bool
+                { 
+                  \exp_not:o \l__nmc_formula_dup_tl
+                  \bool_if:NTF \l__nmc_vv_multline_bool
+                    { \exp_not:o \l__nmc_vv_display_tl }
+                    { 
+                      \mathchoice{ \exp_not:o \l__nmc_vv_display_tl }
+                          { \exp_not:o \l__nmc_vv_inline_tl }{}{} 
+                    }
+                  \rightarrow \exp_not:N \quad 
+                } 
+              \seq_use:Nn \l_tmpa_seq { ,\ }
+              \l__nmc_punc_tl
+              \exp_not:o \l__nmc_math_delimii_tl
+            }
+        \__nmc_plus_reuse:nNN { \l__nmc_recur_reuse_int } \l_tmpc_seq \l_tmpb_seq 
+      }
+    \l_nmc_result_tl
+  }
+\cs_new_protected:Npn \__nmc_recur_result:NN #1#2
+  {
+    \int_zero:N \l_tmpa_int
+    \seq_map_inline:Nn \l__nmc_recur_result_seq
+      { 
+        \int_compare:nNnTF { \l_tmpa_int } < { \l__nmc_recur_first_int }
+          { \seq_put_right:Nn #1 { ##1 } }
+          {
+            \int_compare:nTF { \l_tmpa_int = \l__nmc_recur_first_int 
+                < \l__nmc_recur_total_int - \l__nmc_recur_last_int }
+              { \seq_put_right:Nn #1 { \ldots } }
+              {
+                \int_compare:nNnT { 1 + \l_tmpa_int } > 
+                    { \l__nmc_recur_total_int - \l__nmc_recur_last_int }
+                  { 
+                    \seq_put_right:Nn #1 { ##1 }
+                    \seq_put_right:Nn #2 { ##1 }
+                    \seq_put_right:Nx \l_tmpc_seq { \int_eval:n { \l_tmpa_int + \l__nmc_recur_subscr_ini_int } }
+                  }
+              }
+          }
+        \int_incr:N \l_tmpa_int
+      }
+    \bool_if:NT \l__nmc_recur_ellipsis_bool
+      { \seq_put_right:Nn #1{ \ldots } }
+  }
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\keys_define:nn { numerica-plus }
+  { 
+    iter-do             .int_set:N = \l__nmc_iter_total_int,
+    iter-see-last       .int_set:N = \l__nmc_iter_view_int,
+    iter-max-iterations .int_set:N = \l__nmc_iter_max_int,
+    iter-extra-rounding .int_set:N = \l__nmc_iter_extra_int,
+    iter-reuse          .int_set:N = \l__nmc_iter_reuse_int,
+
+    iter-do             .default:n = 5,
+    iter-see-last       .default:n = 4,
+    iter-max-iterations .default:n = 100,
+    iter-extra-rounding .default:n = 0,
+    iter-reuse          .default:n = 0,
+%
+    solve-max-steps      .int_set:N = \l__nmc_solve_max_int,
+    solve-extra-rounding .int_set:N = \l__nmc_solve_extra_int,
+    solve-first-step      .tl_set:N = \l__nmc_solve_step_tl,
+    solve-reuse          .int_set:N = \l__nmc_solve_reuse_int,
+
+    solve-max-steps      .default:n = 100,
+    solve-extra-rounding .default:n = 0,
+    solve-first-step     .default:n = 1,
+    solve-reuse          .default:n = 0,
+%
+    recur-do         .int_set:N = \l__nmc_recur_total_int,
+    recur-see-first  .int_set:N = \l__nmc_recur_first_int,
+    recur-see-last   .int_set:N = \l__nmc_recur_last_int,
+    recur-reuse      .int_set:N = \l__nmc_recur_reuse_int,
+    
+    recur-do         .default:n = 7,
+    recur-see-first  .default:n = 3,
+    recur-see-last   .default:n = 2,
+    recur-reuse      .default:n = 0
+  }
+\keys_set_known:nn { numerica-plus } 
+  { 
+    iter-do,iter-see-last,iter-max-iterations,
+    iter-extra-rounding,iter-reuse,
+    solve-variable,solve-first-step,solve-max-steps,
+    solve-extra-rounding,solve-reuse,
+    recur-do,recur-see-first,recur-see-last,recur-reuse
+  }
+\keys_define:nn { numerica/iter }
+  {
+    var    .tl_set:N = \l__nmc_iter_var_tl,
+    +     .int_set:N = \l__nmc_iter_extra_int,
+    max   .int_set:N = \l__nmc_iter_max_int,
+    do    .int_set:N = \l__nmc_iter_total_int,
+    see   .int_set:N = \l__nmc_iter_view_int,
+    reuse .int_set:N = \l__nmc_iter_reuse_int
+  }
+\keys_define:nn { numerica/solve }
+  {
+    var    .tl_set:N = \l__nmc_solve_var_tl,
+    +     .int_set:N = \l__nmc_solve_extra_int,
+    max   .int_set:N = \l__nmc_solve_max_int,
+    dvar   .tl_set:N = \l__nmc_solve_step_tl,
+    reuse .int_set:N = \l__nmc_solve_reuse_int
+  }
+\keys_define:nn { numerica/recur }
+  {
+    do    .int_set:N = \l__nmc_recur_total_int,
+    see1  .int_set:N = \l__nmc_recur_first_int,
+    see2  .int_set:N = \l__nmc_recur_last_int,
+    ...      .code:n = \bool_set_true:N \l__nmc_recur_ellipsis_bool,
+    reuse .int_set:N = \l__nmc_recur_reuse_int
+  }
+\file_if_exist:nT { numerica-plus.cfg }
+  { 
+    \file_get:nnN { numerica-plus.cfg } {} \l_tmpa_tl
+    \exp_args:NnV \keys_set_known:nn { numerica-plus } \l_tmpa_tl
+  }
+% end of `numerica-plus.sty'.
-- 
cgit v1.2.3

