% This is file `diffcoeff4.sty'. % % 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,l3keys2e,xtemplate} \ProvidesExplPackage {diffcoeff4} {2022/07/30} {4.2} {Write differential coefficients easily and consistently.} % \keys_define:nn { diffcoeff4 } { ISO .bool_set:N = \l__diffcoeff_ISO_bool, spaced .int_set:N = \l__diffcoeff_spaced_int, spaced .default:n = 1, spaced .initial:n = 0, def-file .tl_gset:N = \g__diffcoeff_def_tl, def-file .initial:n = diffcoeff, def-file .default:n = diffcoeff } \ProcessKeysPackageOptions { diffcoeff4 } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \cs_generate_variant:Nn \tl_if_eq:nnTF { nV } \tl_new:N \l__diffcoeff_oporder_tl \tl_new:N \l__diffcoeff_derivand_tl \tl_new:N \l__diffcoeff_type_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_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 \bool_new:N \l__diffcoeff_integ_bool \bool_new:N \l__diffcoeff_spaced_bool \bool_new:N \l__diffcoeff_altsep_bool \int_new:N \l__diffcoeff_vars_int \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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \DeclareObjectType { derivative } { 3 } % defaults: ordinary deriv. values \DeclareTemplateInterface { derivative } { DERIV } { 3 } { op-symbol : tokenlist = d , op-symbol-alt : tokenlist = \KeyValue { op-symbol }, op-order-sep : muskip = 1 mu , derivand-sep : muskip = 3 mu plus 1 mu minus 2 mu, long-var-wrap : choice { dv, d(v), (dv) } = d(v) , denom-term-sep : muskip = 2 mu , term-sep-adjust : muskip = -1 mu , left-delim : tokenlist = \left . , right-delim : tokenlist = \right |, elbowroom : muskip = 0 mu , subscr-nudge : muskip = 0 mu , *-derivand-sep : muskip = \KeyValue { derivand-sep }, *-op-left : boolean = false , *-italic-nudge : muskip = 3 mu , /-derivand-sep : muskip = \KeyValue { derivand-sep }, /-denom-term-sep : muskip = 1 mu , /-left-delim : tokenlist = ( , /-right-delim : tokenlist = ) , /-elbowroom : muskip = 0 mu , /-subscr-nudge : muskip = 0 mu , */-derivand-sep : muskip = \KeyValue { /-derivand-sep }, */-op-wrap : boolean = true } % #1 order spec(seqvar); #2 order override(tlvar) % #3 derivand(tlvar); #4 denominator(seqvar) % #5 subscript(tlvar) \DeclareTemplateCode { derivative } { DERIV } { 3 } { op-symbol = \l__diffcoeff_op_tl, op-symbol-alt = \l__diffcoeff_op_alt_tl, op-order-sep = \l__diffcoeff_oporder_muskip, derivand-sep = \l__diffcoeff_derivsep_muskip, long-var-wrap = { dv = \cs_set_eq:NN \__diffcoeff_wrap_longvars:nn \__diffcoeff_wrap_longvars_dv:nn, d(v) = \cs_set_eq:NN \__diffcoeff_wrap_longvars:nn \__diffcoeff_wrap_longvars_dvi:nn, (dv) = \cs_set_eq:NN \__diffcoeff_wrap_longvars:nn \__diffcoeff_wrap_longvars_dvii:nn, unknown = \cs_set_eq:NN \__diffcoeff_wrap_longvars:nn \__diffcoeff_wrap_longvars_dvi:nn }, denom-term-sep = \l__diffcoeff_varsep_muskip, term-sep-adjust = \l__diffcoeff_sep_adj_muskip, left-delim = \l__diffcoeff_ldelim_tl, right-delim = \l__diffcoeff_rdelim_tl, elbowroom = \l__diffcoeff_elbowrm_muskip , subscr-nudge = \l__diffcoeff_subnudge_muskip, *-derivand-sep = \l__diffcoeff_derivsepi_muskip, *-op-left = \l__diffcoeff_op_left_bool, *-italic-nudge = \l__diffcoeff_opnudge_muskip, /-derivand-sep = \l__diffcoeff_derivsepii_muskip, /-denom-term-sep = \l_tmpb_muskip, /-left-delim = \l__diffcoeff_ldelimi_tl, /-right-delim = \l__diffcoeff_rdelimi_tl, /-elbowroom = \l_tmpc_muskip, /-subscr-nudge = \l_tmpd_muskip, */-derivand-sep = \l__diffcoeff_derivsepiii_muskip, */-op-wrap = \l__diffcoeff_opwrap_bool } { \AssignTemplateKeys \bool_if:NF\l__diffcoeff_integ_bool { \int_compare:nNnT { \l__diffcoeff_format_int } > { 1 } { \__diffcoeff_slash_vals: } \__diffcoeff_build:nnn { #1 } { #2 } { #3 } } } %%%%%%%%%% \cs_new:Npn \__diffcoeff_slash_vals: { \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__diffcoeff_ldelimi_tl \tl_set:NV \l__diffcoeff_rdelim_tl \l__diffcoeff_rdelimi_tl } % #1 diff'and; #2 vars clist; #3 trailing arg \cs_new:Npn \__diffcoeff_build:nnn #1#2#3 { \tl_set:Nn \l__diffcoeff_derivand_tl { #1 } \seq_set_from_clist:Nn \l__diffcoeff_vars_seq { #2 } \bool_if:nT { !\l__diffcoeff_opwrap_bool && \int_compare_p:nNn { \l__diffcoeff_format_int } > { 1 } } { \int_set:Nn \l__diffcoeff_format_int { 4 } } \__diffcoeff_spaced:n { \l__diffcoeff_spaced_int } \bool_if:nTF { ( \l__diffcoeff_altsep_bool && !\l__diffcoeff_spaced_bool ) || ( !\l__diffcoeff_altsep_bool && \l__diffcoeff_spaced_bool ) } { \__diffcoeff_derivsep: } { \tl_put_left:Nn \l__diffcoeff_derivand_tl { \mskip 0 mu } } \tl_if_novalue:nF { #3 } { \l__diffcoeff_ldelim_tl \mskip \l__diffcoeff_elbowrm_muskip } \bool_if:NTF \l__diffcoeff_single_var_bool { \tl_set:Nx \l_tmpa_tl { \seq_use:Nn \l__diffcoeff_vars_seq { , } } \__diffcoeff_single:NNN \l__diffcoeff_tot_order_tl \l__diffcoeff_derivand_tl \l_tmpa_tl } { \int_zero:N \l_tmpa_int \seq_mapthread_function:NNN \l__diffcoeff_orders_seq \l__diffcoeff_vars_seq \__diffcoeff_map_orders:nn \__diffcoeff_mixed:NNN \l__diffcoeff_tot_order_tl \l__diffcoeff_derivand_tl \l__diffcoeff_denom_seq } \tl_if_novalue:nF { #3 } { \mskip \l__diffcoeff_elbowrm_muskip \l__diffcoeff_rdelim_tl \tl_if_empty:nF { #3 } { \c_math_subscript_token { \mskip \l__diffcoeff_subnudge_muskip { #3 } } } } } %%%%%%%%%%%%%%%%%%%% \cs_new_protected:Npn \__diffcoeff_spaced:n #1 { \int_case:nn { \int_sign:n { #1 } } { { 1 } { \bool_set_true:N \l__diffcoeff_spaced_bool } { 0 } { \bool_set_false:N \l__diffcoeff_spaced_bool } { -1 } { \int_compare:nNnTF { 1 } < { \tl_count:N \l__diffcoeff_derivand_tl } { \bool_set_true:N \l__diffcoeff_spaced_bool } { \bool_set_false:N \l__diffcoeff_spaced_bool } } } } \cs_new_protected:Npn \__diffcoeff_derivsep: { \tl_put_left:Nx \l__diffcoeff_derivand_tl { \int_case:nn { \l__diffcoeff_format_int } { { 0 } { \mskip \l__diffcoeff_derivsep_muskip } { 1 } { \mskip \l__diffcoeff_derivsepi_muskip } { 2 } { \mskip \l__diffcoeff_derivsepii_muskip } { 3 } { \mskip \l__diffcoeff_derivsepiii_muskip } { 4 } { \mskip \l__diffcoeff_derivsepiii_muskip } } } } \cs_new:Npn \__diffcoeff_wrap_longvars_dv:nn #1#2 { \l__diffcoeff_op_alt_tl { {}#2 }^{ #1 } } \cs_new:Npn \__diffcoeff_wrap_longvars_dvi:nn #1#2 { \l__diffcoeff_op_alt_tl { {}(#2) }^{ #1 } } \cs_new:Npn \__diffcoeff_wrap_longvars_dvii:nn #1#2 { (\l__diffcoeff_op_alt_tl { {}#2) }^{ #1 } } % (ptl) form denom #1 from orders seq & #2 from vars seq \cs_new_protected:Npn \__diffcoeff_map_orders:nn #1#2 { \tl_if_eq:nnTF { #1 } { 1 } { \seq_put_right:Nn \l__diffcoeff_denom_seq { \l__diffcoeff_op_alt_tl { #2 } } } { \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:Nn \l__diffcoeff_denom_seq { \__diffcoeff_wrap_longvars:nn { #1\vphantom{)} } { #2 } } } } } % #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_derivand_tl { \__diffcoeff_denom_single:NN #1 #3 } } % #1 total order; #2 derivand; #3 denom seq \cs_new_protected:Npn \__diffcoeff_mixed:NNN #1#2#3 { \__diffcoeff_numer:N #1 \__diffcoeff_form_deriv:NNn \l__diffcoeff_oporder_tl \l__diffcoeff_derivand_tl { \__diffcoeff_denom_sep:N #3 } } \cs_new:Npn \__diffcoeff_denom_sep:N #1 { \int_zero:N \l_tmpa_int \seq_map_inline:Nn #1 { \int_incr:N \l_tmpa_int ##1 \int_compare:nNnT { \l_tmpa_int } < { \l__diffcoeff_vars_int } { \seq_pop:NN \l__diffcoeff_orders_seq \l_tmpa_tl \str_if_eq:VnTF \l_tmpa_tl { 1 } { \mskip \l__diffcoeff_varsep_muskip } { \mskip \muskip_eval:n { \l__diffcoeff_varsep_muskip + \l__diffcoeff_sep_adj_muskip } } } } } % #1(tl) total order \cs_new_protected: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 } } { \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 { \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_protected:Npn \__diffcoeff_denom_single:NN #1#2 { \tl_if_eq:nVTF { 1 } #1 { \l__diffcoeff_op_alt_tl {}#2 } { \int_compare:nNnTF { \tl_count:N #2 } = { 1 } { \l__diffcoeff_op_alt_tl {}#2^{ #1 } } { \__diffcoeff_wrap_longvars:nn { #1\vphantom) } { #2 } } } } % #1 op+order; #2 diff'iand; #3 denom % 0 frac; 1 frac append; 2 slash ; 3 ( slash ) append; 4 slash append \cs_new:Npn \__diffcoeff_form_deriv:NNn #1#2#3 { \int_case:nn { \l__diffcoeff_format_int } { { 0 } { \frac { #1 #2 } { #3 } } { 1 } { \frac { #1 } { #3 } #2 } { 2 } { #1 #2 / #3 } { 3 } { ( #1 / #3 ) #2 } { 4 } { #1 / #3 #2 } } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % differential % #1 variant; #2 = space in mu before d (0--9) % note \group_end placement for \vec{x} etc \NewDocumentCommand \dl { d.. t- m } { \group_begin: \bool_set_true:N \l__diffcoeff_integ_bool \bool_set_true:N \l__diffcoeff_single_var_bool \seq_set_from_clist:Nn \l__diffcoeff_orders_seq { 1 } \tl_set:Nn \l__diffcoeff_tot_order_tl { 1 } \IfValueTF { #1 } { \tl_set:Nn \l__diffcoeff_type_tl { .#1 } } { \tl_set:Nn \l__diffcoeff_type_tl { } } \UseInstance { derivative } { ord\l__diffcoeff_type_tl } \c_empty_tl \c_empty_seq \c_empty_tl \tl_if_in:NnTF \c__diffcoeff_digits_tl { #3 } { \mskip \IfBooleanT #2 { - }#3 mu \l__diffcoeff_op_tl \group_end: } { \l__diffcoeff_op_tl \group_end: {} #3 } } \NewDocumentCommand \negmu {} { \mskip -1 mu } \NewDocumentCommand \nilmu {} { \mskip 0 mu } \NewDocumentCommand \onemu {} { \mskip 1 mu } \NewDocumentCommand \twomu {} { \mskip 2 mu } % derivative % #1(tl) = name of variant; #2(*)= append diff'iand boolean % #3(clist) = orders of diff. in each var.; #4(tl) = order override % #5(bool) spacing switch; #6(tl) = diff'iand; #7( / ) = slash boolean % #8(clist) = vars of diff.; #9(tl) = pt of eval./vars held const \NewDocumentCommand \diff { d.. s O{1} o t! >{\TrimSpaces} m t/ m !o } { \group_begin: \IfBooleanTF #5 { \bool_set_true:N \l__diffcoeff_altsep_bool } { \bool_set_false:N \l__diffcoeff_altsep_bool } \seq_set_from_clist:Nn \l__diffcoeff_orders_seq { #3 } \int_set:Nn \l_tmpb_int { \seq_count:N \l__diffcoeff_orders_seq } \int_set:Nn \l__diffcoeff_vars_int { \clist_count:n { #8 } } \int_compare:nNnTF { \l__diffcoeff_vars_int } = { 1 } { \bool_set_true:N \l__diffcoeff_single_var_bool } { \int_compare:nNnTF { \l__diffcoeff_vars_int } < { \l_tmpb_int } { \msg_error:nnxxxx { diffcoeff } { numbers-conflict } { \int_use:N \l__diffcoeff_vars_int } { \int_use:N \l_tmpb_int } { \seq_use:Nn \l__diffcoeff_orders_seq { , } } { \clist_use:nn { #8 } { , } } } { % pad orders seq if nec. \int_step_inline:nnnn { 1 + \l_tmpb_int } { 1 } { \l__diffcoeff_vars_int } { \seq_put_right:Nn \l__diffcoeff_orders_seq { 1 } } } } % 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 } } \IfValueTF { #1 } { \tl_set:Nn \l__diffcoeff_type_tl { .#1 } } { \tl_set:Nn \l__diffcoeff_type_tl { } } % append? slash? \int_zero:N \l__diffcoeff_format_int \IfBooleanT #2 { \int_incr:N \l__diffcoeff_format_int } \IfBooleanT #7 { \int_add:Nn \l__diffcoeff_format_int { 2 } } \UseInstance { derivative } { ord\l__diffcoeff_type_tl } {#6}{#8}{#9} \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 } } \cs_new:Npn \__diffcoeff_digest_expr:n #1 { \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+ } { \__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 } \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 } } % #1 curr tok (tl); #2 <== curr tok ndx (int) \cs_new_protected: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(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 } } } % transitions from the signed state % #1(tl) curr tok; #2(int) 0, curr state; #3 curr tok ndx \cs_new_protected:Npn \__diffcoeff_sgn_transitions:nNN #1#2#3 { \int_case:nnT { #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 } } { 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 } } } { \int_set_eq:NN #2 #3 } } % transitions from the numeric state % #1 = curr. tok.; #2 = 0, curr. state; #3 curr. tok. index \cs_new_protected:Npn \__diffcoeff_num_transitions:nNN #1#2#3 { \int_case:nnT { #3 } { { 0 } % tok = s { \tl_put_right:NV\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_if_in:nnTF { ^ \times * / \div } { #1 } { \msg_error:nnxxx { diffcoeff } { order-specification } { \seq_use:Nn \l__diffcoeff_orders_seq { , } } { #1 } { number } } { \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 = ) { \tl_put_right:NV \l__diffcoeff_nos_tl { \l__diffcoeff_paren_tl * \l__diffcoeff_curr_num_tl } } } { \int_set_eq:NN #2 #3 } } % 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:nnT { #3 } { { 0 } % tok = s { \int_compare:nNnTF { \l__diffcoeff_parenvar_int } = { 0 } { \__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 } } { \tl_put_right:Nn \l__diffcoeff_curr_var_tl { #1 } \int_set:Nn #3 { 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 = ( { \tl_put_right:Nn \l__diffcoeff_curr_var_tl { #1 } \int_set:Nn #3 { 2 } \int_incr:N \l__diffcoeff_parenvar_int } { 4 } % tok = ) { \int_compare:nNnTF { \l__diffcoeff_parenvar_int } = { 0 } { \__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_put_right:Nn \l__diffcoeff_curr_var_tl { #1 } \int_set:Nn #3 { 2 } \int_decr:N \l__diffcoeff_parenvar_int } } } { \int_set_eq:NN #2 #3 } } % 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 { \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 } { \seq_use:Nn \l__diffcoeff_orders_seq { , } } { #1 } { ) } } } % #1 is var. (tlvar); #2 is num. (tlvar); #3 num. coeff. (tlvar) \cs_new:Npn \__diffcoeff_store_var:NNN #1#2#3 { \prop_get:NVNF \l__diffcoeff_vars_prop #1 \l_tmpa_tl { \tl_clear:N \l_tmpa_tl } \tl_put_right:NV \l_tmpa_tl { #2 * #3 } \prop_put:NVV \l__diffcoeff_vars_prop #1 \l_tmpa_tl } % #1 (propv) key=var, val=coeff; #2 <= total order \cs_new_protected:Npn \__diffcoeff_evaluate:NN #1#2 { \prop_map_inline:Nn #1 { \seq_put_left:Nn \l_tmpa_seq { ##1 } } \seq_sort:Nn \l_tmpa_seq { \int_compare:nNnTF { \tl_count:n { ##1 } } < { \tl_count:n { ##2 } } { \sort_return_same: } { \sort_return_swapped: } } \seq_map_inline:Nn \l_tmpa_seq { \prop_pop:NnN #1 { ##1 } \l_tmpb_tl \seq_put_right:Nx \l_tmpb_seq { \int_eval:n \l_tmpb_tl } } \tl_clear:N \l_tmpa_tl \seq_mapthread_function:NNN \l_tmpa_seq \l_tmpb_seq \__diffcoeff_tot_order:nn \exp_args:NV \tl_if_head_eq_charcode:nNTF \l_tmpa_tl + { \tl_set:Nx \l_tmpb_tl { \tl_tail:N \l_tmpa_tl } \int_compare:nNnT { \l__diffcoeff_nos_int } > { 0 } { \tl_put_left:Nn \l__diffcoeff_nos_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 } \cs_new:Npn \__diffcoeff_tot_order:nn #1#2 { \int_compare:nNnTF { #2 } > { 0 } { \int_compare:nNnTF { #2 } = { 1 } { \tl_put_left:Nn \l_tmpa_tl { +#1 } } { \tl_put_left:Nn \l_tmpa_tl { +#2#1 } } } { \int_compare:nNnT { #2 } < { 0 } { \int_compare:nNnTF { #2 } = { -1 } { \tl_put_right:Nn \l_tmpa_tl { -#1 } } { \tl_put_right:Nn \l_tmpa_tl { #2#1 } } } } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 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 } } { \IfInstanceExistTF { derivative } { ord.#1 } { \EditInstance { derivative } { ord.#1 } { #2 } } { \DeclareInstance { derivative } { ord.#1 } { DERIV } { #2 } } } } % relic from version 1 \NewDocumentCommand \diffset { o } { \msg_warning:nn { diffcoeff } { obsolete } } % ordinary & D \DeclareInstance { derivative } { ord } { DERIV } { } \bool_if:NTF \l__diffcoeff_ISO_bool { \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} } } { \diffdef { D } { op-symbol = D } } % partial \diffdef { p } { op-symbol = \partial , left-delim = \left ( , right-delim = \right ) , subscr-nudge = -6 mu } \NewDocumentCommand \diffp {} { \diff.p. } \NewDocumentCommand \dlp {} { \dl.p. } % delta \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 \file_if_exist:nT { \g__diffcoeff_def_tl.def } { \file_input:n { \g__diffcoeff_def_tl.def } } %%%%%%%%%%%%%%%%%%%% % Jacobian \NewDocumentCommand \jacob { m t/ m } { \group_begin: \IfBooleanTF #2 { \partial(#1) / \partial(#3) } { \frac{ \partial(#1) } { \partial(#3) } } \group_end: } %%%%%%%%%%%%%%%%%%%% % messages \msg_new:nnn { diffcoeff } { order-specification } { #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 is~superseded~by~the~\diffdef\ command.~\msg_see_documentation_text:n { diffcoeff } } \msg_new:nnn { diffcoeff } { numbers-conflict } { #2~orders~of~differentiation~specified~for~#1~variables;~ orders~[#3]\ (\msg_line_context:)~for~variables~#4. } % end of file diffcoeff4.sty