diff options
author | Karl Berry <karl@freefriends.org> | 2018-12-04 23:09:17 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2018-12-04 23:09:17 +0000 |
commit | d92cee8eff42fa304294a3e5f674062c8c745632 (patch) | |
tree | ab9459068cfe1631be3fb144a7004bb42fdce55d /Master/texmf-dist/tex/latex | |
parent | 3865c2c0c5140b0d004e5944bd0afb132df802d7 (diff) |
diffcoeff (4dec18)
git-svn-id: svn://tug.org/texlive/trunk@49317 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex')
-rw-r--r-- | Master/texmf-dist/tex/latex/diffcoeff/diffcoeff-doc.def | 121 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/diffcoeff/diffcoeff.sty | 1232 |
2 files changed, 724 insertions, 629 deletions
diff --git a/Master/texmf-dist/tex/latex/diffcoeff/diffcoeff-doc.def b/Master/texmf-dist/tex/latex/diffcoeff/diffcoeff-doc.def new file mode 100644 index 00000000000..34a03b2c7f2 --- /dev/null +++ b/Master/texmf-dist/tex/latex/diffcoeff/diffcoeff-doc.def @@ -0,0 +1,121 @@ +% file `diffcoeff.def' +% variant forms of derivative +% 2018-11-12 +% Andrew Parsloe ajparsloe@gmail.com +% +% paren, up, Up, wrapall, nabla, left, svrule +% pvrule, padrift, psqbra, pDelta, pleft, ptxt, pscr +%%%%%%%%%% ordinary %%%%%%%%%% +% ( ) for pt of eval. +\diffdef { paren } + { + left-delim = \left ( , + right-delim = \right ), + subscr-nudge = -6 mu + } + +% upright +\diffdef { up } + { + op-symbol = \mathrm{d}, + op-order-sep = 0 mu , + /-op-order-sep = 0 mu + } + +\diffdef { Up } + { + op-symbol = \mathrm{D}, + op-order-sep = 0 mu , + /-op-order-sep = 0 mu + } + +% wrap long vars: (d longvar) +\diffdef { wrapall } {long-var-wrap = (dv)} + +% nabla in numerator, d in denominator +\diffdef { nabla } + { + op-symbol = \nabla, + op-symbol-alt = d + } + +% align op left; no italic nudge +\diffdef { left } + { + *-op-left = true, + *-italic-nudge = 0 mu + } + +% slash-form: vrule for pt of eval +\diffdef { svrule } + { + /-left-delim = , + /-right-delim = | + } + +%%%%%%%%%% partial %%%%%%%%%% +% partial, vrule for pt of eval. +\diffdef { pvrule } { op-symbol = \partial } + +% partial, no subscr nudge (adrift in a sea of white space) +\diffdef { padrift } + { + op-symbol = \partial, + left-delim = \left ( , + right-delim = \right ), + subscr-nudge = 0 mu + } + +% partial, [ ] for pt of eval. +\diffdef { psqbra } + { + op-symbol = \partial, + left-delim = \left [ , + right-delim = \right ], + subscr-nudge = 0 mu + } + +% Delta as partial deriv. +\diffdef { pDelta } + { + op-symbol = \Delta , + op-order-sep = 0 mu , + /-op-order-sep = 0 mu , + left-delim = \left ( , + right-delim = \right ), + subscr-nudge = -6 mu + } + +% align op left; italic nudge +\diffdef { pleft } + { + op-symbol = \partial, + *-op-left = true , + *-italic-nudge = 3 mu , + left-delim = \left ( , + right-delim = \right ), + subscr-nudge = -3 mu + } + +% partial, textstyle +\diffdef { ptxt } + { + op-symbol = \partial, + denom-term-sep = 1 mu , + left-delim = \left ( , + right-delim = \right ), + elbowroom = -2 mu , + subscr-nudge = -3 mu + } + +% partial, scriptstyle +\diffdef { pscr } + { + op-symbol = \partial, + op-order-sep = 0 mu , + denom-term-sep = 0 mu , + left-delim = \left ( , + right-delim = \right ), + subscr-nudge = -3 mu + } + diff --git a/Master/texmf-dist/tex/latex/diffcoeff/diffcoeff.sty b/Master/texmf-dist/tex/latex/diffcoeff/diffcoeff.sty index 47dd6b869a7..2a5e48a9582 100644 --- a/Master/texmf-dist/tex/latex/diffcoeff/diffcoeff.sty +++ b/Master/texmf-dist/tex/latex/diffcoeff/diffcoeff.sty @@ -1,705 +1,679 @@ % This is file `diffcoeff.sty'. % -% This program is free software; you can redistribute it and/or modify it -% under the terms of the GNU General Public License as published by the -% Free Software Foundation; either version 2 of the License, or (at your -% option) any later version. +% This work may be distributed and/or modified under the conditions +% of the LaTeX Project Public License, either version 1.3c +% (2008-05-04) of this license or any later version; see +% http://www.latex-project.org/lppl.txt % % Andrew Parsloe ajparsloe@gmail.com % \RequirePackage{expl3} -\RequirePackage{xparse} -\ProvidesExplPackage{diffcoeff} {2018/10/25} {1.1} - {Write differential coefficients easily.} - +\RequirePackage{xparse,l3keys2e,xtemplate} +\ProvidesExplPackage {diffcoeff} {2018/12/02} {2} + {Write differential coefficients consistently and easily.} +% +\keys_define:nn { diffcoeff } + { + ISO .bool_gset:N = \g__diffcoeff_ISO_bool, + def-file .tl_gset:N = \g__diffcoeff_def_tl , + def-file .initial:n = diffcoeff , + def-file .default:n = diffcoeff + } +\ProcessKeysPackageOptions { diffcoeff } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\cs_generate_variant:Nn \tl_if_eq:nnF { no } -\cs_generate_variant:Nn \tl_if_eq:nnT { no } -\cs_generate_variant:Nn \tl_if_in:NnTF { NV } -\cs_generate_variant:Nn \prop_pop:NnNT { NV } - +\cs_generate_variant:Nn \tl_if_eq:nnTF { nV } + +\tl_new:N \l__diffcoeff_op_tl +\tl_new:N \l__diffcoeff_op_alt_tl +\tl_new:N \l__diffcoeff_ldelim_tl +\tl_new:N \l__diffcoeff_rdelim_tl +\tl_new:N \l__diffcoeff_oporder_tl +\tl_new:N \l__diffcoeff_differentiand_tl +\tl_new:N \l__diffcoeff_type_tl +\tl_new:N \l__diffcoeff_order_spec_tl +\tl_new:N \l__diffcoeff_denom_tl +\tl_new:N \l__diffcoeff_tot_order_tl +\tl_new:N \l__diffcoeff_curr_num_tl +\tl_new:N \l__diffcoeff_curr_var_tl +\tl_new:N \l__diffcoeff_paren_tl +\tl_new:N \l__diffcoeff_trailing_tl + +\tl_const:Nn \c__diffcoeff_digits_tl { 1234567890 } + +\seq_new:N \l__diffcoeff_orders_seq +\seq_new:N \l__diffcoeff_vars_seq +\seq_new:N \l__diffcoeff_denom_seq +\seq_new:N \l__diffcoeff_paren_seq + +\prop_new:N \l__diffcoeff_vars_prop + +\bool_new:N \l__diffcoeff_op_left_bool +\bool_new:N \l__diffcoeff_single_var_bool +\bool_new:N \l__diffcoeff_opwrap_bool + +\int_new:N \l__diffcoeff_format_int +\int_new:N \l__diffcoeff_curr_tok_int +\int_new:N \l__diffcoeff_curr_state_int +\int_new:N \l__diffcoeff_nos_int +\int_new:N \l__diffcoeff_parenvar_int + +\muskip_new:N \l__diffcoeff_oporder_muskip +\muskip_new:N \l__diffcoeff_opnudge_muskip +\muskip_new:N \l__diffcoeff_elbowrm_muskip +\muskip_new:N \l__diffcoeff_subnudge_muskip +\muskip_new:N \l__diffcoeff_varsep_muskip +\muskip_new:N \l_tmpc_muskip +\muskip_new:N \l_tmpd_muskip %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% variables -\tl_new:N \g_diffco_d_ldelim_tl -\tl_new:N \g_diffco_d_rdelim_tl -\tl_new:N \g_diffco_p_ldelim_tl -\tl_new:N \g_diffco_p_rdelim_tl - -\tl_new:N \l__diffco_rentiand_tl -\tl_new:N \l__diffco_phantom_tl -\tl_new:N \g_diffco_dop_tl -\tl_new:N \l__diffco_denom_tl -\tl_new:N \l__diffco_coeff_tl - -\clist_new:N \l__diffco_order_clist -\tl_new:N \l__diffco_order_spec_tl - -\bool_new:N \g__diffco_erent_shape_bool -\bool_new:N \l__diffco_no_parens_bool -\bool_new:N \l__diffco_override_bool -\bool_new:N \l__diffco_vars_noted_bool +% Derivatives +% #1 order spec(seqvar) +% #2 order override(tlvar) +% #3 differentiand(tlvar) +% #4 denominator(seqvar) +% #5 subscript(tlvar) +\DeclareObjectType { derivative } { 5 } + +% defaults: ordinary deriv. values +\DeclareTemplateInterface { derivative } { DERIV } { 5 } + { + op-symbol : tokenlist = d , + op-symbol-alt : tokenlist = \KeyValue { op-symbol }, + op-order-sep : muskip = 1 mu , + /-op-order-sep : muskip = 1 mu , + *-op-left : boolean = false , + *-italic-nudge : muskip = 3 mu , + */-op-wrap : boolean = true , + long-var-wrap : choice { dv, d(v), (dv) } + = d(v) , + denom-term-sep : muskip = 2 mu , + /-denom-term-sep : muskip = 1 mu , + left-delim : tokenlist = \left . , + right-delim : tokenlist = \right |, + elbowroom : muskip = 0 mu , + subscr-nudge : muskip = 0 mu , + /-left-delim : tokenlist = ( , + /-right-delim : tokenlist = ) , + /-elbowroom : muskip = 0 mu , + /-subscr-nudge : muskip = 0 mu + } -\tl_new:N \l__diffco_orders_in_tl -\tl_new:N \l__diffco_order_tl - -\tl_new:N \l__diffco_curr_tok_tl -\tl_new:N \l__diffco_curr_term_tl - -\int_new:N \l__diffco_curr_tok_int -\int_new:N \l__diffco_curr_state_int - -\prop_new:N \l__diffco_vars_prop -\tl_new:N \l__diffco_vars_tl -\clist_new:N \l__diffco_vars_clist - -\tl_new:N \l__diffco_curr_var_tl -\tl_new:N \l__diffco_nos_tl -\tl_new:N \l__diffco_nos_aux_tl - -\tl_new:N \l__diffco_alg_tl -\tl_new:N \l__diffco_alg_aux_tl -\tl_new:N \l__diffco_alg_expr_tl - -\tl_const:Nn \c__diffco_digits_tl { 1234567890 } - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\keys_define:nn { diffcoeff } +\DeclareTemplateCode { derivative } { DERIV } { 5 } { - roman .bool_gset:N = \g_diffco_roman_bool, - roman .default:n = { false }, - d-delims .code:n = { - \tl_gset:Nx \g_diffco_d_ldelim_tl { \left \use_i:nn #1 } - \tl_gset:Nx \g_diffco_d_rdelim_tl - { \right \use_ii:nn #1 } - }, - d-delims .default:n = { .| }, - p-delims .code:n = { - \tl_gset:Nx \g_diffco_p_ldelim_tl { \left \use_i:nn #1 } - \tl_gset:Nx \g_diffco_p_rdelim_tl - { \right \use_ii:nn #1 } - }, - p-delims .default:n = { () }, - d-nudge .code:n = { \tl_gset:Nn \g_diffco_d_nudge_tl { \mskip #1 mu } }, - d-nudge .default:n = { 0 }, - p-nudge .code:n = { \tl_gset:Nn \g_diffco_p_nudge_tl { \mskip #1 mu } }, - p-nudge .default:n = { -6 }, - sep .code:n = { \tl_gset:Nn \g_diffco_sep_tl { \mskip #1 mu } }, - sep .default:n = { 2 }, - d-sep .code:n = { \tl_gset:Nn \g_diffco_d_sep_tl { \mskip #1 mu } }, - d-sep .default:n = { 1 }, - p-sep .code:n = { \tl_gset:Nn \g_diffco_p_sep_tl { \mskip #1 mu } }, - p-sep .default:n = { 1 }, - } - -\DeclareDocumentCommand \diffset { o } + op-symbol = \l__diffcoeff_op_tl , + op-symbol-alt = \l__diffcoeff_op_alt_tl , + op-order-sep = \l__diffcoeff_oporder_muskip , + /-op-order-sep = \l_tmpa_muskip , + *-op-left = \l__diffcoeff_op_left_bool , + *-italic-nudge = \l__diffcoeff_opnudge_muskip , + */-op-wrap = \l__diffcoeff_opwrap_bool , + long-var-wrap = { + dv = \cs_set_eq:NN \__diffcoeff_wrap_longvars:NN + \__diffcoeff_wrap_none:NN, + d(v) = \cs_set_eq:NN \__diffcoeff_wrap_longvars:NN + \__diffcoeff_wrap_var:NN , + (dv) = \cs_set_eq:NN \__diffcoeff_wrap_longvars:NN + \__diffcoeff_wrap_dvar:NN, + unknown = \cs_set_eq:NN \__diffcoeff_wrap_longvars:NN + \__diffcoeff_wrap_var:NN + } , + denom-term-sep = \l__diffcoeff_varsep_muskip , + /-denom-term-sep = \l_tmpb_muskip , + left-delim = \l__diffcoeff_ldelim_tl , + right-delim = \l__diffcoeff_rdelim_tl , + elbowroom = \l__diffcoeff_elbowrm_muskip , + subscr-nudge = \l__diffcoeff_subnudge_muskip, + /-left-delim = \l_tmpa_tl , + /-right-delim = \l_tmpb_tl , + /-elbowroom = \l_tmpc_muskip , + /-subscr-nudge = \l_tmpd_muskip + } + { + \AssignTemplateKeys + \int_compare:nNnT { \l__diffcoeff_format_int } > { 1 } + { \__diffcoeff_slash_vals: } + \__diffcoeff_build:NNNNN #1#2#3#4#5 + } +%%%%%%%%%% +\cs_new:Npn \__diffcoeff_slash_vals: { - \IfValueTF { #1 } - { - \clist_if_empty:nTF { #1 } - { \keys_set:nn { diffcoeff } { roman,d-delims,p-delims, - d-nudge,p-nudge,sep,d-sep,p-sep } } - { \keys_set:nn { diffcoeff } { #1 } } - } - { - \keys_set:nn { diffcoeff } { roman,d-delims,p-delims, - d-nudge,p-nudge,sep,d-sep,p-sep } - } + \muskip_set:Nn \l__diffcoeff_oporder_muskip \l_tmpa_muskip + \muskip_set:Nn \l__diffcoeff_varsep_muskip \l_tmpb_muskip + \muskip_set:Nn \l__diffcoeff_elbowrm_muskip \l_tmpc_muskip + \muskip_set:Nn \l__diffcoeff_subnudge_muskip \l_tmpd_muskip + \tl_set:NV \l__diffcoeff_ldelim_tl \l_tmpa_tl + \tl_set:NV \l__diffcoeff_rdelim_tl \l_tmpb_tl } - -% now set the defaults -\diffset - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% Ordinary differential coefficient - -% #1 = the order -% #2 = differentiand -% #3 = the variable of differentiation -% #4 = point of evaluation - -\NewDocumentCommand \diff{ s o m t/ m g } +\cs_new:Npn \__diffcoeff_build:NNNNN #1#2#3#4#5 + { + \bool_if:NF \l__diffcoeff_opwrap_bool + { \int_set:Nn \l__diffcoeff_format_int { 4 } } + \exp_args:NV\tl_if_novalue:nF #5 + { \l__diffcoeff_ldelim_tl \mkern \l__diffcoeff_elbowrm_muskip } + \bool_if:NTF \l__diffcoeff_single_var_bool + { \__diffcoeff_single:NNN #2 #3 #4 } + { + \seq_mapthread_function:NNN #1 #4 \__diffcoeff_map_orders:nn + \__diffcoeff_mixed:NNN #2 #3 \l__diffcoeff_denom_seq + } + \exp_args:NV\tl_if_novalue:nF #5 + { + \mkern \l__diffcoeff_elbowrm_muskip \l__diffcoeff_rdelim_tl + \exp_args:NV\tl_if_empty:nF #5 + { + \c_math_subscript_token + { \mskip \l__diffcoeff_subnudge_muskip #5 } + } + } + } +%%%%%%%%%%%%%%%%%%%% +% (ptl) form denom from #1 orders, & #2 vars, seqs +\cs_new:Npn \__diffcoeff_map_orders:nn #1#2 { - \group_begin: - % roman or italic? - \bool_if:NF \g__diffco_erent_shape_bool - { \__diffco_shape:N d } - - \IfValueTF { #2 } - { - \tl_set:Nn \l__diffco_order_tl { ^{ \g_diffco_d_sep_tl #2 } } - \int_compare:nNnTF { \tl_count:n { #5 } } > { \c_one } - { \tl_set:Nn \l__diffco_denom_tl { (#5)^{ #2 } } } - { \tl_set:Nn \l__diffco_denom_tl { #5^{ #2 } } } - } - { - \tl_set:Nn \l__diffco_order_tl { } - \tl_if_in:nnTF { #5 } { ^ } - { \tl_set:Nn \l__diffco_denom_tl { (#5) } } - { \tl_set:Nn \l__diffco_denom_tl { #5 } } - } - - % position of differentiand: appended (star) or in numerator (no star); - % slash or fraction? - \IfBooleanTF { #1 } - { % differentiand follows diff coeff - \__diffco_phantom:n { #3 } - \tl_set:Nn \l__diffco_coeff_tl + \tl_if_eq:nnTF { #1 } { 1 } + { \seq_put_right:Nn \l__diffcoeff_denom_seq { \l__diffcoeff_op_alt_tl #2 } } { - \IfBooleanTF { #4 } - { % slash (therefore no phantom) - (\g_diffco_dop_tl \l__diffco_order_tl - / - \g_diffco_dop_tl \l__diffco_denom_tl ) - \l__diffco_rentiand_tl - } - { % frac - \frac { \g_diffco_dop_tl \l__diffco_order_tl \l__diffco_phantom_tl } - { \g_diffco_dop_tl \l__diffco_denom_tl } \l__diffco_rentiand_tl - } + \int_compare:nNnTF { \tl_count:n { #2 } } = { 1 } + { + \seq_put_right:Nn \l__diffcoeff_denom_seq + { \l__diffcoeff_op_alt_tl #2^{ #1 } } + } + { + \seq_put_right:Nx \l__diffcoeff_denom_seq + { \__diffcoeff_wrap_longvars:NN { #1 } { #2 } } + } } - } - { % differentiand in numerator - \tl_set:Nn \l__diffco_coeff_tl - { - \IfBooleanTF { #4 } - { % slash - \g_diffco_dop_tl \l__diffco_order_tl #3 - / - \g_diffco_dop_tl \l__diffco_denom_tl - } - { % frac - \frac { \g_diffco_dop_tl \l__diffco_order_tl #3 } - { \g_diffco_dop_tl \l__diffco_denom_tl } - } + } +% #1 order(tlvar) ; #2 diff'iand(tlvar); % #3 denom(tlvar) +\cs_new:Npn \__diffcoeff_single:NNN #1#2#3 + { + \__diffcoeff_numer:N { #1 } + \__diffcoeff_form_deriv:NNn + \l__diffcoeff_oporder_tl + \l__diffcoeff_differentiand_tl + { \__diffcoeff_denom_single:NN #1 #3 } + } +% #1 total order +% #2 differentiand +% #3 denominator seq +\cs_new:Npn \__diffcoeff_mixed:NNN #1#2#3 + { + \__diffcoeff_numer:N #1 + \__diffcoeff_form_deriv:NNn + \l__diffcoeff_oporder_tl + \l__diffcoeff_differentiand_tl + { \seq_use:Nn #3 { \mskip \l__diffcoeff_varsep_muskip } } + } +% #1(tl) total order +\cs_new:Npn \__diffcoeff_numer:N #1 + { + \bool_if:NTF \l__diffcoeff_op_left_bool + { + \tl_set:Nn \l__diffcoeff_oporder_tl + { \mskip \l__diffcoeff_opnudge_muskip } } - } - % pt of eval - \IfNoValueTF { #6 } - { - \l__diffco_coeff_tl - } - { % trailing arg: pt of eval. - \tl_if_empty:nTF { #6 } + { \tl_clear:N \l__diffcoeff_oporder_tl } + \tl_put_right:No \l__diffcoeff_oporder_tl \l__diffcoeff_op_tl + \exp_args:NnV \tl_if_eq:nnF { 1 } #1 { - \l__diffco_coeff_tl + \tl_put_right:Nn \l__diffcoeff_oporder_tl + { \mskip \l__diffcoeff_oporder_muskip ^ { #1 } } } + \bool_if:NT \l__diffcoeff_op_left_bool + { \tl_put_right:Nn \l__diffcoeff_oporder_tl { \hfill } } + } +% #1 order; #2 var +\cs_new:Npn \__diffcoeff_denom_single:NN #1#2 + { + \tl_if_eq:nVTF { 1 } #1 + { \l__diffcoeff_op_alt_tl #2 } { - \g_diffco_d_ldelim_tl \l__diffco_coeff_tl \g_diffco_d_rdelim_tl - \c_math_subscript_token { \g_diffco_d_nudge_tl #6 } + \int_compare:nNnTF { \tl_count:N #2 } = { 1 } + { \l__diffcoeff_op_alt_tl #2^{ #1 } } + { \__diffcoeff_wrap_longvars:NN #1 #2 } } - } - \group_end: - } - -\NewDocumentCommand \Diff { o m m g } - { - \group_begin: - \__diffco_shape:N D - \bool_gset_true:N \g__diffco_erent_shape_bool - \diff[#1]{#2}{#3}{#4} - \bool_gset_false:N \g__diffco_erent_shape_bool - \group_end: - } - -\NewDocumentCommand \diffd { o m m g } - { - \group_begin: - \__diffco_shape:N \delta - \bool_gset_true:N \g__diffco_erent_shape_bool - \diff[#1]{#2}{#3}{#4} - \bool_gset_false:N \g__diffco_erent_shape_bool - \group_end: - } - -\NewDocumentCommand \Diffd { o m m g } - { - \group_begin: - \__diffco_shape:N \Delta - \bool_gset_true:N \g__diffco_erent_shape_bool - \diff[#1]{#2}{#3}{#4} - \bool_gset_false:N \g__diffco_erent_shape_bool - \group_end: } - -\cs_new_nopar:Npn \__diffco_shape:N #1 - { - \bool_if:NTF \g_diffco_roman_bool - { \tl_gset:Nn \g_diffco_dop_tl { \mathrm{ #1} } } - { \tl_gset:Nn \g_diffco_dop_tl { #1 } } - } -%%%%% -\cs_new:Npn \__diffco_append:nn #1#2 - { - \g_diffco_d_ldelim_tl \l__diffco_coeff_tl \g_diffco_d_rdelim_tl - \c_math_subscript_token { \mskip #1 mu #2 } - } - -\cs_new:Npn \__diffco_phantom:n #1 - { - \bool_if:nTF +\cs_new:Npn \__diffcoeff_wrap_none:NN #1#2 + { \l__diffcoeff_op_alt_tl #2^{#1} } +\cs_new:Npn \__diffcoeff_wrap_var:NN #1#2 + { \l__diffcoeff_op_alt_tl (#2)^{#1} } +\cs_new:Npn \__diffcoeff_wrap_dvar:NN #1#2 + { (\l__diffcoeff_op_alt_tl #2)^{#1} } + +% #1 op+order; #2 diff'iand; #3 denom +% 0 frac; 1 frac append; 2 slash ; 3 slash append +\cs_new:Npn \__diffcoeff_form_deriv:NNn #1#2#3 + { + \int_case:nn { \l__diffcoeff_format_int } { - \tl_if_head_eq_meaning_p:nN { #1 } \hfill || - \tl_if_head_eq_meaning_p:nN { #1 } \hfil + { 0 } { \frac { #1 #2 } { #3 } } + { 1 } { \frac { #1 } { #3 } { #2 } } + { 2 } { #1 #2 / #3 } + { 3 } { ( #1 / #3 ) { #2 } } + { 4 } { #1 / #3 { #2 } } + } + } +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% create new instances or edit existing ones +% #1 = name; #2 = key-value list +\NewDocumentCommand \diffdef { > { \TrimSpaces } m m } + { + \tl_if_empty:nTF { #1 } + { + \EditTemplateDefaults { derivative } + { DERIV } { #2 } + \EditInstance { derivative } { ord } { #2 } } - { \l__diffco_phantom_aux:nn #1\q_stop } { - \bool_if:nTF - { - \tl_if_head_eq_meaning_p:nN { #1 } \hspace || - \tl_if_head_eq_meaning_p:nN { #1 } \hphantom - } - { \l__diffco_phantom_aux:nnn #1\q_stop } - { \tl_set:Nn \l__diffco_rentiand_tl { #1 } } + \IfInstanceExistTF { derivative } { ord.#1 } + { \EditInstance { derivative } { ord.#1 } { #2 } } + { + \DeclareInstance { derivative } { ord.#1 } + { DERIV } { #2 } + } } } +% superseded relic from version 1 +\NewDocumentCommand \diffset { o } + { \msg_warning:nn { diffcoeff } { obsolete } } -\cs_new:Npn \l__diffco_phantom_aux:nn #1#2\q_stop +% ordinary +\DeclareInstance { derivative } { ord } { DERIV } { } +\bool_if:NTF \g__diffcoeff_ISO_bool { - \tl_set:Nn \l__diffco_phantom_tl { #1 } - \tl_set:Nn \l__diffco_rentiand_tl { #2 } + \diffdef {} + { + op-symbol = \mathrm{d}, + op-order-sep = 0 mu , + left-delim = \left ( , + right-delim = \right ) , + subscr-nudge = -6 mu + } + \diffdef { D } { op-symbol = \mathrm{D} } } - -\cs_new:Npn \l__diffco_phantom_aux:nnn #1#2#3\q_stop + { \diffdef { D } { op-symbol = D } } + +% partial +\diffdef { p } { - \tl_set:Nn \l__diffco_phantom_tl { #1 { #2 } } - \tl_set:Nn \l__diffco_rentiand_tl { #3 } + op-symbol = \partial , + left-delim = \left ( , + right-delim = \right ) , + subscr-nudge = -6 mu } - -%%%%%%%%%%%%%%%%%%%% -% Partial differential coefficient. -% #1 (star) = append differentiand boolean -% #2 = comma list of the orders of diff. in each var.; -% #3 = order override for the numerator; #4 = differentiand; -% #5 slash / boolean; #6 = comma list of vars of diff.; -% #7 = list of vars held const. -\NewDocumentCommand \diffp{ s o o m t/ m g } +\NewDocumentCommand \diffp { } { \diff.p. } + +\diffdef { delta } + { + op-symbol = \delta , + op-order-sep = 0 mu + } +\diffdef { Delta } + { + op-symbol = \Delta , + op-order-sep = 0 mu + } +% for compatibility with version 1 +\NewDocumentCommand \Diff { } { \diff.D. } +\NewDocumentCommand \diffd { } { \diff.delta. } +\NewDocumentCommand \Diffd { } { \diff.Delta. } + +% user-defined variants +\file_if_exist:nT { \g__diffcoeff_def_tl.def } + { \file_input:n { \g__diffcoeff_def_tl.def } } +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% derivative +% #1(tl) = name of variant +% #2(*) = append differentiand boolean +% #3(clist) = orders of diff. in each var. +% #4(tl) = order override +% #5(tl) = differentiand +% #6 ( / ) = slash boolean +% #7(clist) = vars of diff. in order +% #8(tl) = pt of eval./vars held constant +% #9(tl) = #8 for backwards compatibility +\NewDocumentCommand \diff{ d.. s O{1} o m t/ m !O{#9} g } { - \group_begin: - - % diff. order list - \tl_clear:N \l__diffco_order_clist - \IfValueT { #2 } - { - \clist_set:Nn \l__diffco_order_clist { #2 } - \tl_set:Nx \l__diffco_order_spec_tl - { [\clist_use:Nn \l__diffco_order_clist { , }]} - } - - % order list override - \IfValueT { #3 } - { - \bool_set_true:N \l__diffco_override_bool - \tl_set:Nn \l__diffco_order_tl { #3 } - } - - \__diffco_orders:Nn \l__diffco_order_clist { #6 } + \group_begin: + \tl_set:Nn \l__diffcoeff_differentiand_tl { #5 } + \tl_set:Nn \l__diffcoeff_trailing_tl { #8 } - % position of differentiand - \IfBooleanTF { #1 } - { % appended - \__diffco_phantom:n { #4 } - \tl_set:Nn \l__diffco_coeff_tl - { - \IfBooleanTF { #5 } - { % slash (therefore no phantom) - ( \partial \__diffco_omit_order_if_i:N - \l__diffco_order_tl - / - \l__diffco_denom_tl ) \l__diffco_rentiand_tl - } - { % frac - \frac { \partial \__diffco_omit_order_if_i:N - \l__diffco_order_tl \l__diffco_phantom_tl } - { \l__diffco_denom_tl } \l__diffco_rentiand_tl - } - } - } - { % in numerator - \tl_set:Nn \l__diffco_coeff_tl - { - \IfBooleanTF { #5 } + \tl_set:Nn \l__diffcoeff_denom_tl { #7 } + \seq_set_split:Nnn \l__diffcoeff_vars_seq { , } { #7 } + + \seq_set_from_clist:Nn \l__diffcoeff_orders_seq { #3 } + \tl_set:Nn \l__diffcoeff_order_spec_tl { [#3] } + + \int_set:Nn \l_tmpa_int { \seq_count:N \l__diffcoeff_vars_seq } + \int_set:Nn \l_tmpb_int { \seq_count:N \l__diffcoeff_orders_seq } + \int_compare:nNnTF { \l_tmpa_int } = { 1 } + { \bool_set_true:N \l__diffcoeff_single_var_bool } + { + \int_compare:nNnTF { \l_tmpa_int } < { \l_tmpb_int } { - \partial \__diffco_omit_order_if_i:N \l__diffco_order_tl #4 - / \l__diffco_denom_tl + \msg_error:nnxx { diffcoeff } { numbers-conflict } + { \int_use:N \l_tmpa_int } { \int_use:N \l_tmpb_int } } - { - \frac { \partial - \__diffco_omit_order_if_i:N \l__diffco_order_tl - #4 } { \l__diffco_denom_tl } + { % pad orders seq if nec. + \int_step_inline:nnnn + { 1 + \l_tmpb_int } { 1 } { \l_tmpa_int } + { \seq_put_right:Nn \l__diffcoeff_orders_seq { 1 } } + \tl_set:NV \l__diffcoeff_denom_tl \l__diffcoeff_vars_seq } - } - } - - \IfNoValueTF { #7 } - { \l__diffco_coeff_tl } - { - \tl_if_empty:nTF { #7 } - { - \l__diffco_coeff_tl } - { - \g_diffco_p_ldelim_tl \l__diffco_coeff_tl \g_diffco_p_rdelim_tl - \c_math_subscript_token { \g_diffco_p_nudge_tl #7 } + % override/calc total order + \IfValueTF { #4 } + { \tl_set:Nn \l__diffcoeff_tot_order_tl { #4 } } + { + \bool_if:NTF \l__diffcoeff_single_var_bool + { \tl_set:Nn \l__diffcoeff_tot_order_tl { #3 } } + { + \__diffcoeff_calc_tot_order:NN \l__diffcoeff_orders_seq + \l__diffcoeff_tot_order_tl + } } - } - \group_end: - } % end of \diffp - -\NewDocumentCommand \jacob { m m } - { % need extra braces in denom for clist manipulations - \diffp{ (#1) }{ { {{(#2)}} } } + \IfValueT { #1 } { \tl_set:Nn \l__diffcoeff_type_tl { .#1 } } + \int_zero:N \l__diffcoeff_format_int + % append? slash? + \IfBooleanT #2 { \int_incr:N \l__diffcoeff_format_int } + \IfBooleanT #6 { \int_add:Nn \l__diffcoeff_format_int { 2 } } + + \UseInstance { derivative } { ord\l__diffcoeff_type_tl } + \l__diffcoeff_orders_seq + \l__diffcoeff_tot_order_tl + \l__diffcoeff_differentiand_tl + \l__diffcoeff_denom_tl + \l__diffcoeff_trailing_tl + \group_end: + } % end of \diff +%%%%%%%%%%%%%%%%%%% +% #2(seq) expr in; #1(tlv) expr out +\cs_new:Npn \__diffcoeff_calc_tot_order:NN #1 #2 + { + \tl_clear:N \l__diffcoeff_nos_tl + \exp_args:Nx\__diffcoeff_digest_expr:n { \seq_use:Nn #1 { + } } + \prop_if_empty:NTF \l__diffcoeff_vars_prop + { \tl_set:NV #2 \l__diffcoeff_nos_tl } + { \__diffcoeff_evaluate:NN \l__diffcoeff_vars_prop #2 } } - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% #1 is the clist of diff. orders -% #2 is the tl of variables (if commas present treat as clist) -\cs_new:Npn \__diffco_orders:Nn #1#2 +\cs_new:Npn \__diffcoeff_digest_expr:n #1 { - \int_zero:N \l_tmpa_int - \tl_clear:N \l_tmpb_tl - \clist_clear:N \l_tmpa_clist - \clist_clear:N \l_tmpb_clist - \clist_clear:N \l__diffco_vars_clist - - \clist_set:Nn \l__diffco_vars_clist { #2 } - \clist_map_inline:Nn \l__diffco_vars_clist - { - \bool_set_false:N \l__diffco_no_parens_bool - - % get order of each variable - \clist_pop:NNF #1 \l_tmpa_tl - { \tl_set:Nn \l_tmpa_tl { 1 } } - - \tl_if_eq:noT { 1 } \l_tmpa_tl - { \bool_set_true:N \l__diffco_no_parens_bool } - - \clist_put_right:NV \l_tmpa_clist \l_tmpa_tl - - % create the denominator - \tl_clear:N \l_tmpb_tl - \bool_if:nTF - { - \int_compare_p:nNn { \tl_count:n { ##1 } } = { \c_one } - || - \l__diffco_no_parens_bool - } - { \tl_put_right:Nn \l_tmpb_tl { \partial ##1 } } - { \tl_put_right:Nn \l_tmpb_tl { \partial (##1) } } - - \tl_if_eq:noF { 1 } \l_tmpa_tl + \tl_set:Nn \l__diffcoeff_curr_num_tl { + } + \tl_set:Nn \l__diffcoeff_paren_tl { +1 } + \tl_set:Nn \l__diffcoeff_nos_tl { 0 } + \int_zero:N \l__diffcoeff_curr_state_int + \int_zero:N \l__diffcoeff_curr_tok_int + \tl_map_inline:nn { #1+ } { - \tl_put_right:Nn \l_tmpb_tl { ^ } - \tl_put_right:Nx \l_tmpb_tl { { \l_tmpa_tl } } + \__diffcoeff_get_curr_ndx:nN { ##1 } \l__diffcoeff_curr_tok_int + \__diffcoeff_transitions:nNN { ##1 } + \l__diffcoeff_curr_state_int \l__diffcoeff_curr_tok_int } - - \clist_put_right:No \l_tmpb_clist \l_tmpb_tl - } % end of inline map - - % numerator order - \bool_if:NF \l__diffco_override_bool - { - \tl_set:Nx \l__diffco_orders_in_tl { \clist_use:Nn \l_tmpa_clist {+} } - \diff_simplify_orders:NN \l__diffco_orders_in_tl \l__diffco_order_tl - } - - % denominator - \tl_set:Nx \l__diffco_denom_tl { \clist_use:Nn - \l_tmpb_clist { \g_diffco_sep_tl } } + \int_set:Nn \l__diffcoeff_nos_int { \l__diffcoeff_nos_tl } + \tl_set:Nx \l__diffcoeff_nos_tl { \int_use:N \l__diffcoeff_nos_int } + \int_compare:nNnT { \l__diffcoeff_nos_int } = { 0 } + { \tl_clear:N \l__diffcoeff_nos_tl } } - -% don't display order 1 superscript -\cs_new:Npn \__diffco_omit_order_if_i:N #1 - { - \tl_if_eq:noF { 1 } #1 - { ^{ \g_diffco_p_sep_tl \l__diffco_order_tl } } - } -%%%%%%%%%%%%%%%%%%%%%% -% #1 is expr. in; #2 is expr. out -\cs_new:Npn \diff_simplify_orders:NN #1 #2 - { - \tl_clear:N \l__diffco_nos_tl - - \__diffco_digest_expr:NNNN \l__diffco_orders_in_tl \l__diffco_nos_tl - \l__diffco_alg_tl \l__diffco_vars_prop - - \__diffco_eval_nos:N \l__diffco_nos_tl - - \tl_if_empty:NF \l__diffco_alg_tl - { \__diffco_eval_vars:NN \l__diffco_alg_tl \l__diffco_vars_prop } - - \__diffco_manicure_result:NNN \l__diffco_nos_tl \l__diffco_alg_tl #2 +% #1 curr tok (tl); #2 <== curr tok ndx (int) +\cs_new:Npn \__diffcoeff_get_curr_ndx:nN #1#2 + { + \tl_if_in:NnTF \c__diffcoeff_digits_tl { #1 } + { \int_set:Nn #2 { 1 } } % digit + { + \str_case:nnF { #1 } + { + { + } { \int_set:Nn #2 { 0 } } + { - } { \int_set:Nn #2 { 0 } } + { ( } { \int_set:Nn #2 { 3 } } + { ) } { \int_set:Nn #2 { 4 } } + } + { \int_set:Nn #2 { 2 } } % var + } } - -% #1 is the expression; #2 (tl) receives the numerical part; -% #3 (tl) receives the algebraic part; #4 (prop) receives the vars -\cs_new:Npn \__diffco_digest_expr:NNNN #1#2#3#4 - { - \tl_put_right:Nn #1 { + } - \tl_set:Nn \l__diffco_curr_term_tl { + } - \int_set:Nn \l__diffco_curr_state_int { \c_zero } - \int_set:Nn \l__diffco_curr_tok_int { \c_zero } - \tl_clear:N #3 - \prop_clear:N #4 - - \tl_map_inline:Nn #1 - { - \tl_set:Nn \l__diffco_curr_tok_tl { ##1 } - \__diffco_get_curr_index:NN ##1 \l__diffco_curr_tok_int - \__diffco_compare_states:NNNNN \l__diffco_curr_state_int - \l__diffco_curr_tok_int #2#3#4 - } - \tl_if_empty:NT #2 { \tl_set:Nn #2 { 0 } } +% #1(tl) curr tok; #2(int) curr state; #3(int) curr tok ndx +\cs_new:Npn \__diffcoeff_transitions:nNN #1#2#3 + { + \int_case:nn { #2 } + { + { 0 } % sgn + - + { \__diffcoeff_sgn_transitions:nNN { #1 }#2#3 } + { 1 } % num + { \__diffcoeff_num_transitions:nNN { #1 }#2#3 } + { 2 } % alg + { \__diffcoeff_alg_transitions:nNN { #1 }#2#3 } + { 4 } % ) + { \__diffcoeff_rpar_transitions:nNN { #1 }#2#3 } + } } - -% #1 contains current token (tl); #2 receives current state (int) -\cs_new:Npn \__diffco_get_curr_index:NN #1#2 +% transitions from the signed state +% #1(tl) curr tok; #2(int) 0, curr state; #3 curr tok ndx +\cs_new:Npn \__diffcoeff_sgn_transitions:nNN #1#2#3 { - \tl_if_in:NnTF \c__diffco_digits_tl { #1 } - { % digit - \int_set:Nn #2 { \c_one } - } - { - \tl_case:NnF #1 - { - + { \int_set_eq:NN #2 \c_zero } - - { \int_set_eq:NN #2 \c_zero } - ( { - \msg_error:nnxx { diffcoeff } { unknown_token } - { \l__diffco_order_spec_tl } { parentheses } + \int_case:nnTF { #3 } + { + { 0 } % tok = s + { + \tl_if_eq:nVTF { #1 } \l__diffcoeff_curr_num_tl + { \tl_set:Nn \l__diffcoeff_curr_num_tl { + } } + { \tl_set:Nn \l__diffcoeff_curr_num_tl { - } } + } + { 1 } % tok = d + { \tl_put_right:Nn \l__diffcoeff_curr_num_tl { #1 } } + { 2 } % tok = v + { + \tl_put_right:Nn \l__diffcoeff_curr_num_tl { 1 } + \tl_set:Nn \l__diffcoeff_curr_var_tl { #1 } } - ^ { - \msg_error:nnxx { diffcoeff } { unknown_token } - { \l__diffco_order_spec_tl } { superscript } + { 3 } % tok = ( + { + \seq_push:NV \l__diffcoeff_paren_seq \l__diffcoeff_paren_tl + \tl_put_left:NV \l__diffcoeff_paren_tl \l__diffcoeff_curr_num_tl + \tl_set:Nn \l__diffcoeff_curr_num_tl { + } + \int_set:Nn #3 { 0 } } - } - { - \token_if_math_subscript:NTF #1 - { - \msg_error:nnxx { diffcoeff } { unknown_token } - { \l__diffco_order_spec_tl } { subscript } - } - { \int_set_eq:NN #2 \c_two } % var - } - } + } + { \int_set_eq:NN #2 #3 } + { + \msg_error:nnxxx { diffcoeff } { order-specification } + { \l__diffcoeff_order_spec_tl } { #1 } { sign } + } } - -% #1 (int) is curr. state; #2 (int) is curr token index; -% #3 (tl) receives the numerical part; -% #4 (tl) receives the algebraic part; -% #5 (prop) receives the vars -\cs_new:Npn \__diffco_compare_states:NNNNN #1#2#3#4#5 +% transitions from the numeric state +% #1 = curr. tok.; #2 = 0, curr. state; #3 curr. tok. index +\cs_new:Npn \__diffcoeff_num_transitions:nNN #1#2#3 { - \int_case:nn { #1 } - { - { \c_zero } % sgn - { - \int_case:nn { #2 } + \int_case:nnTF { #3 } + { + { 0 } % tok = s { - { \c_zero } % tok = s + \__diffcoeff_store_num:NNN \l__diffcoeff_nos_tl + \l__diffcoeff_paren_tl \l__diffcoeff_curr_num_tl + \tl_set:Nn \l__diffcoeff_curr_num_tl { #1 } + } + { 1 } % tok = d + { \tl_put_right:Nn \l__diffcoeff_curr_num_tl { #1 } } + { 2 } % tok = v + { \tl_set:Nn \l__diffcoeff_curr_var_tl { #1 } } + { 3 } % tok = ( + { + \seq_push:NV \l__diffcoeff_paren_seq \l__diffcoeff_paren_tl + \tl_put_left:Nn \l__diffcoeff_paren_tl { * } + \tl_put_left:NV \l__diffcoeff_paren_tl \l__diffcoeff_curr_num_tl + \tl_set:Nn \l__diffcoeff_curr_num_tl { + } + \int_set:Nn #3 { 0 } + } + { 4 } % tok = ) + { + \__diffcoeff_store_num:NNN \l__diffcoeff_nos_tl + \l__diffcoeff_paren_tl \l__diffcoeff_curr_num_tl + } + } + { + \int_set_eq:NN #2 #3 } + { + \msg_error:nnxxx { diffcoeff } { order-specification } + { \l__diffcoeff_order_spec_tl } { #1 } { number } + } + } +% transitions from the algebraic state +% #1 = curr. tok.; #2 = 2, curr. state; #3 curr. tok. index +\cs_new:Npn \__diffcoeff_alg_transitions:nNN #1#2#3 + { + \int_case:nnTF { #3 } + { + { 0 } % tok = s + { + \int_compare:nNnTF { \l__diffcoeff_parenvar_int } = { 0 } { - \tl_if_eq:NNTF \l__diffco_curr_term_tl \l__diffco_curr_tok_tl - { \tl_set:Nn \l__diffco_curr_term_tl { + } } - { \tl_set:Nn \l__diffco_curr_term_tl { - } } + \__diffcoeff_store_var:NNN \l__diffcoeff_curr_var_tl + \l__diffcoeff_paren_tl \l__diffcoeff_curr_num_tl + \tl_clear:N \l__diffcoeff_curr_var_tl + \tl_set:Nn \l__diffcoeff_curr_num_tl { #1 } } - { \c_one } % tok = d - { \__diffco_term_append:NN #1#2 } - { \c_two } % tok = v { - \tl_put_right:Nn \l__diffco_curr_term_tl { 1 } - \__diffco_term_var_append:NN #1#2 + \tl_put_right:Nn \l__diffcoeff_curr_var_tl { #1 } + \int_set:Nn #3 { 2 } } } - } - { \c_one } % num - { - \int_case:nn { #2 } + { 1 } % tok = d + { + \tl_put_right:Nn \l__diffcoeff_curr_var_tl { #1 } + \int_set:Nn #3 { 2 } + } + { 2 } % tok = v + { \tl_put_right:Nn \l__diffcoeff_curr_var_tl { #1 } } + { 3 } % tok = ( { - { \c_zero } % tok = s - { - \tl_put_right:NV #3 \l__diffco_curr_term_tl - \tl_clear:N \l__diffco_curr_term_tl - \__diffco_term_append:NN #1#2 - } - { \c_one } % tok = d - { \__diffco_term_append:NN #1 \c_one } - { \c_two } % tok = v - { \__diffco_term_var_append:NN #1#2 } + \tl_put_right:Nn \l__diffcoeff_curr_var_tl { #1 } + \int_set:Nn #3 { 2 } + \int_incr:N \l__diffcoeff_parenvar_int } - } - { \c_two } % alg - { - \int_case:nn { #2 } + { 4 } % tok = ) { - { \c_zero } % tok = s + \int_compare:nNnTF { \l__diffcoeff_parenvar_int } = { 0 } { - \tl_put_right:NV #4 \l__diffco_curr_term_tl - \tl_clear:N \l__diffco_curr_term_tl - \bool_if:NF \l__diffco_vars_noted_bool - { \__diffco_store_var:NN #5 \l__diffco_curr_var_tl } - \tl_clear:N \l__diffco_curr_var_tl - \__diffco_term_append:NN #1#2 + \__diffcoeff_store_var:NNN \l__diffcoeff_curr_var_tl + \l__diffcoeff_paren_tl \l__diffcoeff_curr_num_tl + \tl_clear:N \l__diffcoeff_curr_var_tl } - { \c_one } % tok = d - { - \__diffco_term_var_append:NN #1 \c_two - \msg_error:nnx { diffcoeff } { variable_digit_sequence } - { \l__diffco_order_spec_tl } + { + \tl_put_right:Nn \l__diffcoeff_curr_var_tl { #1 } + \int_set:Nn #3 { 2 } + \int_decr:N \l__diffcoeff_parenvar_int } - { \c_two } % tok = v - { \__diffco_term_var_append:NN #1 \c_two } } - } - } + } + { \int_set_eq:NN #2 #3 } + { + \msg_error:nnxxx { diffcoeff } { order-specification } + { \l__diffcoeff_order_spec_tl } { #1 } + { variable } + } } - -% #1 current state; #2 current token index -\cs_new:Npn \__diffco_term_var_append:NN #1#2 +% transitions from the ) state +% #1 = curr. tok.; #2 = 4, curr. state; #3 curr. tok. index +\cs_new:Npn \__diffcoeff_rpar_transitions:nNN #1#2#3 { - \tl_put_right:NV \l__diffco_curr_term_tl \l__diffco_curr_tok_tl - \tl_put_right:NV \l__diffco_curr_var_tl \l__diffco_curr_tok_tl - \int_set_eq:NN #1 #2 + \int_compare:nNnTF { \int_mod:nn { #3 } { 4} } = { 0 } + { + \tl_set:Nn \l__diffcoeff_curr_num_tl { #1 } + \seq_pop:NN \l__diffcoeff_paren_seq \l__diffcoeff_paren_tl + \int_set_eq:NN #2 #3 + } + { + \msg_error:nnxxx { diffcoeff } { order-specification } + { \l__diffcoeff_order_spec_tl } { #1 } { ) } + } } - -% #1 current state; #2 current token index -\cs_new:Npn \__diffco_term_append:NN #1#2 +% #1=store (tlvar); #2=num. coeff. (tlvar); #3=num.(tlvar) +\cs_new:Npn \__diffcoeff_store_num:NNN #1#2#3 { - \tl_put_right:NV \l__diffco_curr_term_tl \l__diffco_curr_tok_tl - \int_set_eq:NN #1 #2 - } - -% #1 is prop list; #2 is tl containing var -\cs_new:Npn \__diffco_store_var:NN #1 #2 - { - \int_set:Nn \l_tmpa_int { \exp_args:NV \tl_count_tokens:n #2 } - \prop_get:NVNTF #1 \l_tmpa_int \l_tmpa_tl - { - \tl_put_right:Nn \l_tmpa_tl { , } - \tl_put_right:NV \l_tmpa_tl #2 - \prop_put:NVV #1 \l_tmpa_int \l_tmpa_tl - } - { - \prop_put:NVV #1 \l_tmpa_int #2 - } - } - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% evals numerical expr. in #1, which receives the -% evaluated expr. -\cs_new:Npn \__diffco_eval_nos:N #1 + \tl_put_right:NV #1 #2 + \tl_put_right:Nn #1 { * } + \tl_put_right:NV #1 #3 + } +% #1 is var. (tlvar); #2 is num. (tlvar); #3 num. coeff. (tlvar) +\cs_new:Npn \__diffcoeff_store_var:NNN #1#2#3 { - \int_set:Nn \l_tmpa_int { #1 } - \tl_set:Nx #1 { \int_use:N \l_tmpa_int } - \int_compare:nNnT { \l_tmpa_int } > { \c_zero } - { \tl_put_left:Nn #1 { + } } + \prop_get:NVNF \l__diffcoeff_vars_prop #1 \l_tmpa_tl + { \tl_clear:N \l_tmpa_tl } + \__diffcoeff_store_num:NNN \l_tmpa_tl #2 #3 + \prop_put:NVV \l__diffcoeff_vars_prop #1 \l_tmpa_tl } - -% #1 (tl) has algebraic part & receives eval. expression -% #2 (prop) contains the variables -% The idea is to remove each var but leave coeffs, split into -% num & alg parts, eval. the num part for the net coeff of var -\cs_new:Npn \__diffco_eval_vars:NN #1#2 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% #1 (prop) vars (keys) & coeffs (vals); #2 total order +\cs_new:Npn \__diffcoeff_evaluate:NN #1#2 { - \bool_set_true:N \l__diffco_vars_noted_bool - \prop_set_eq:NN \l_tmpa_prop #2 - \int_set_eq:NN \l_tmpa_int \c_one - \bool_until_do:nn { \prop_if_empty_p:N #2 } - { - \prop_pop:NVNT #2 \l_tmpa_int \l_tmpa_tl + \prop_map_inline:Nn #1 + { + \int_compare:nNnF { \int_eval:n { ##2 } } = { 0 } + { + \seq_put_right:Nx \l_tmpa_seq + { { +\int_eval:n { ##2 } } { ##1 } } + } + } + \seq_sort:Nn \l_tmpa_seq { - \tl_put_left:Nn \l_tmpa_tl { , } - \tl_put_left:NV \l__diffco_vars_tl \l_tmpa_tl + \int_compare:nNnTF + { \tl_count:V { \use_ii:nn ##1 } } < + { \tl_count:V { \use_ii:nn ##2 } } + { \sort_return_swapped: } + { \sort_return_same: } } - \int_incr:N \l_tmpa_int - } - - \clist_set:NV \l__diffco_vars_clist \l__diffco_vars_tl - \clist_remove_duplicates:N \l__diffco_vars_clist - - \clist_map_inline:Nn \l__diffco_vars_clist - { - \tl_replace_all:Nnn #1 { ##1 } { } - \__diffco_digest_expr:NNNN #1 \l__diffco_nos_aux_tl \l__diffco_alg_aux_tl - \l_tmpa_prop - - \__diffco_eval_nos:N \l__diffco_nos_aux_tl - - \__diffco_cumulate_expr:NnN \l__diffco_nos_aux_tl { ##1 } - \l__diffco_alg_expr_tl - - \tl_set_eq:NN #1 \l__diffco_alg_aux_tl - \tl_clear:N \l__diffco_nos_aux_tl - \tl_clear:N \l__diffco_alg_aux_tl - } - - \tl_set_eq:NN #1 \l__diffco_alg_expr_tl + \tl_set:Nx \l_tmpa_tl { \seq_use:Nn \l_tmpa_seq { } } + \seq_set_split:NnV \l_tmpa_seq {} \l_tmpa_tl + \tl_clear:N \l_tmpa_tl + \seq_map_inline:Nn \l_tmpa_seq + { + \tl_if_eq:nnTF { +-1 } { ##1 } + { \tl_put_right:Nn \l_tmpa_tl { - } } + { + \tl_if_eq:nnTF { +1 } { ##1 } + { \tl_put_right:Nn \l_tmpa_tl { + } } + { \tl_put_right:Nn \l_tmpa_tl { ##1 } } + } + } + \tl_replace_all:Nnn \l_tmpa_tl { +- } { - } + \exp_args:NV \tl_if_head_eq_charcode:nNTF \l_tmpa_tl + + { + \int_compare:nNnT { \l__diffcoeff_nos_int } > { 0 } + { \tl_put_left:Nn \l__diffcoeff_nos_tl { + } } + \tl_set:Nx \l_tmpb_tl { \tl_tail:N \l_tmpa_tl } + \tl_concat:NNN #2 \l_tmpb_tl \l__diffcoeff_nos_tl + } + { + \int_compare:nNnTF { \l__diffcoeff_nos_int } > { 0 } + { \tl_concat:NNN #2 \l__diffcoeff_nos_tl \l_tmpa_tl } + { \tl_concat:NNN #2 \l_tmpa_tl \l__diffcoeff_nos_tl } + } + \tl_set_rescan:Nno #2 { } #2 } - -% #1 is num coeff; #2 is var; #3 is cumulating expr. (All tl.) -\cs_new:Npn \__diffco_cumulate_expr:NnN #1#2#3 +%%%%%%%%%%%%%%%%%%%% +% Jacobian +\NewDocumentCommand \jacob { m t/ m } { - \int_case:nnF { #1 } - { - { 0 } { \prg_do_nothing: } - { +1 } { \tl_put_right:Nn #3 { + #2 } } - { -1 } { \tl_put_right:Nn #3 { - #2 } } - } - { - \tl_put_right:NV #3 { #1 } - \tl_put_right:Nn #3 { #2 } - } + \group_begin: + \IfBooleanTF #2 + { \partial(#1) / \partial(#3) } + { \frac{ \partial(#1) } { \partial(#3) } } + \group_end: } - -% alg. part precedes num. part unless alg. starts -% with - and nums > 0. #1 nums, #2 alg, #3 output -\cs_new:Npn \__diffco_manicure_result:NNN #1#2#3 - { % alg < 0 ? - \exp_args:NV \tl_if_head_eq_charcode:nNTF #2 - - { - \int_compare:nNnTF { #1 } > { \c_zero } - { % nums > 0 - \tl_concat:NNN #3 #1 #2 - } - { % nums =< 0 - \seq_set_split:NnV \l_tmpa_seq { + } #2 - \seq_pop:NN \l_tmpa_seq \l_tmpa_tl - \tl_set:Nx \l_tmpb_tl { \seq_use:Nn \l_tmpa_seq { + } } - \int_compare:nNnF { #1 } = { \c_zero } - { \tl_concat:NNN \l_tmpa_tl \l_tmpa_tl #1 } - \tl_concat:NNN #3 \l_tmpb_tl \l_tmpa_tl - } - } - { % alg >= 0 - \int_compare:nNnTF { #1 } = { \c_zero } - { \tl_set_eq:NN #3 #2 } - { \tl_concat:NNN #3 #2 #1 } - } - - % if everything cancels, output 0 - \tl_if_empty:NTF #3 { \tl_set:Nn #3 { 0 } } - { - % trim initial + sign - \exp_args:NV \tl_if_head_eq_charcode:nNT #3 + - { \tl_set:Nx #3 { \tl_tail:N #3 } } - } - } -%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%% % messages -\tl_gset:Nn \g__diffcoeff_info_text: - { Use~the~order-override~option~to~specify~the~overall~order~of~ - differentiation. } - -\msg_new:nnnn { diffcoeff } { unknown_token } - { Unimplemented~in~diffcoeff.sty:~#2~in~the~order~specification~#1~ - \msg_line_context:. } - { \g__diffcoeff_info_text: } - -\msg_new:nnnn { diffcoeff } { variable_digit_sequence } - { Unimplemented~in~diffcoeff.sty:~a~digit~follows~a~variable~in~the~order~ - specification~#1~\msg_line_context:. } - { \g__diffcoeff_info_text: } - -%% version history -% 1.1 Fix message handling mess; avoids conflict with mhchem.sty
\ No newline at end of file +\msg_new:nnn { diffcoeff } { order-specification } + { + Is~this~intended:~#3~followed~by~#2~in~the~order~ + specification~#1~\msg_line_context:?~Diffcoeff~cannot~calculate~ + the~overall~order~of~differentiation~in~this~case.~ + Use~the~order-override~option~to~enter~the~overall~order. + } +\msg_new:nnn { diffcoeff } { obsolete } + { + Obsolete~command:~\diffset has~been~superseded~by~the~\diffdef\ + command.~\msg_see_documentation_text:n { diffcoeff } + } +\msg_new:nnn { diffcoeff } { numbers-conflict } + { + #2~orders~specified~for~#1~variables;~\l__diffcoeff_order_spec_tl + \ (\msg_line_context:)~for~variables~\l__diffcoeff_denom_tl. + } +% end of file diffcoeff.sty
\ No newline at end of file |