%% This is file `skmath.sty', generated from `skmath.tex' (key `package').
%% skmath improved math commands
%%
%% Copyright (C) 2012-2019 by Simon Sigurdhsson <sigurdhsson@gmail.com>
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
%% of this license or (at your option) any later version.
%% The latest version of this license is in
%%   http://www.latex-project.org/lppl.txt
%% and version 1.3 or later is part of all distributions of LaTeX
%% version 2005/12/01 or later.
%%
%% This work has the LPPL maintenance status `maintained'.
%%
%% The Current Maintainer of this work is Simon Sigurdhsson.
%%
%% This work consists of the file skmath.tex
%% and the derived file skmath.sty.

\RequirePackage{expl3,l3keys2e,xparse}
\ProvidesExplPackage{skmath}
    {2018/12/29}{0.5}{improved math commands}
\PassOptionsToPackage{intlimits,sumlimits,namelimits}{amsmath}
\RequirePackage{amssymb,mathtools,xfrac}
\msg_new:nnnn{skmath}{undefined-macro}{The~macro~`\token_to_str:N#1'~was~undefined!}
  {This~is~an~error~in~the~notation~option~handling.~Please~file~an~issue\\
   on~Github~(https://github.com/urdh/skmath/issues)~with~a~copy~of~this\\
   message~attached~as~well~as~a~list~of~the~options~passed~to~`skmath'.}
\cs_gset_nopar:Npn\__skmath_integral_d:{
  \msg_critical:nnn{skmath}{undefined-macro}{\__skmath_integral_d:}
}
\cs_gset_nopar:Npn\__skmath_natural_log_e:{
  \msg_critical:nnn{skmath}{undefined-macro}{\__skmath_natural_log_e:}
}
\cs_gset_nopar:Npn\__skmath_imaginary_unit:n#1{
  \msg_critical:nnn{skmath}{undefined-macro}{\__skmath_imaginary_unit:n}
}
\cs_gset_nopar:Npn\__skmath_total_derivative_d:{
  \msg_critical:nnn{skmath}{undefined-macro}{\__skmath_total_derivative_d:n}
}
\keys_define:nn{skmath / internal}{
  % More on this:
  % * http://en.wikipedia.org/wiki/Typographical_conventions_in_mathematical_formulae
  % * ISO 80000-2
  % * http://www.tug.org/TUGboat/Articles/tb18-1/tb54becc.pdf
  % * http://tex.stackexchange.com/q/14821/66
  integral-d .choice:,
  integral-d .value_required:n = true,
  integral-d / upright .code:n = { \cs_gset_nopar:Npn\__skmath_integral_d:{{\operator@font d}} },
  integral-d / slanted .code:n = { \cs_gset_nopar:Npn\__skmath_integral_d:{{d}} },
  isomath .bool_set:N = \g__skmath_load_isomath_bool,
  isomath .value_required:n = true,
  natural-log .choice:,
  natural-log .value_required:n = true,
  natural-log / upright .code:n = { \cs_gset_nopar:Npn\__skmath_natural_log_e:{{\operator@font e}} },
  natural-log / slanted .code:n = { \cs_gset_nopar:Npn\__skmath_natural_log_e:{{e}} },
  imaginary-unit .choice:,
  imaginary-unit .value_required:n = true,
  imaginary-unit / upright .code:n = { \cs_gset_nopar:Npn\__skmath_imaginary_unit:n##1{{\operator@font ##1}} },
  imaginary-unit / slanted .code:n = { \cs_gset_nopar:Npn\__skmath_imaginary_unit:n##1{{##1}} },
  complex-part-symbols .bool_set_inverse:N = \g__skmath_iso_complex_parts_bool,
  complex-part-symbols .value_required:n = true,
  total-derivative-d .choice:,
  total-derivative-d .value_required:n = true,
  total-derivative-d / upright .code:n = { \cs_gset_nopar:Npn\__skmath_total_derivative_d:{{\operator@font d}} },
  total-derivative-d / slanted .code:n = { \cs_gset_nopar:Npn\__skmath_total_derivative_d:{{d}} },
}
\keys_define:nn{skmath}{
  commonsets .bool_set:N = \g__skmath_define_common_sets_bool,
  commonsets .default:n = true,
  commonsets .initial:n = false,
  % TODO: write tests for the notation option
  notation .choice:,
  notation / iso .meta:nn = {skmath / internal}{
    integral-d = upright,
    isomath    = true,
    natural-log = upright,
    imaginary-unit = upright,
    complex-part-symbols = false,
    total-derivative-d = upright,
  },
  notation / german .meta:nn = {skmath / internal}{
    integral-d = upright,
    isomath    = true,
    natural-log = slanted, %???
    imaginary-unit = slanted, %???
    complex-part-symbols = true, %???
    total-derivative-d = upright, %???
  },
  notation / english .meta:nn = {skmath / internal}{
    integral-d = slanted,
    isomath    = true,
    natural-log = slanted, %???
    imaginary-unit = slanted, %???
    complex-part-symbols = true, %???
    total-derivative-d = slanted, %???
  },
  notation / legacy .meta:nn = {skmath / internal}{
    integral-d = upright,
    isomath    = true,
    natural-log = slanted,
    imaginary-unit = slanted,
    complex-part-symbols = true,
    total-derivative-d = slanted,
  },
  % Possibly more style sets... ?
  notation .initial:n = legacy, % Or is it? Perhaps a legacy option is required.
  notation .value_required:n = true,
  % Note also that the styles should probably affect isomath and/or other packages.
}
\ProcessKeysOptions{skmath}
\bool_if:NTF\g__skmath_load_isomath_bool{
  \RequirePackage{isomath}
}{
  % TODO: check if there is an alternative package we should load here.
}
\prg_new_conditional:Npnn\__skmath_if_novalue_or_empty:n#1{F}{
  \IfNoValueTF{#1}{
    \prg_return_true:
  }{
    \tl_if_empty:nTF{#1}{
      \prg_return_true:
    }{
      \prg_return_false:
    }
  }
}
\cs_new_nopar:Npn\__skmath_parens:n#1{
  \__skmath_if_novalue_or_empty:nF{#1}{\left(#1\right)}
}
\bool_if:NT\g__skmath_define_common_sets_bool{
  \NewDocumentCommand\N{}{\ensuremath{\mathbb{N}}}
  \NewDocumentCommand\Z{}{\ensuremath{\mathbb{Z}}}
  \NewDocumentCommand\Q{}{\ensuremath{\mathbb{Q}}}
  \NewDocumentCommand\R{}{\ensuremath{\mathbb{R}}}
  \NewDocumentCommand\C{}{\ensuremath{\mathbb{C}}}
}
\DeclareDocumentCommand\ii{}{\ensuremath{\__skmath_imaginary_unit:n{i}}}
\DeclareDocumentCommand\jj{}{\ensuremath{\__skmath_imaginary_unit:n{j}}}
\bool_if:NTF\g__skmath_iso_complex_parts_bool{
  \cs_new_eq:NN\__skmath_Re:\Re
  \DeclareDocumentCommand\Re{m}{\ensuremath{\__skmath_Re:\__skmath_parens:n{#1}}}
}{
  \DeclareDocumentCommand\Re{m}{\ensuremath{{\operator@font Re}{#1}}}
}
\bool_if:NTF\g__skmath_iso_complex_parts_bool{
  \cs_new_eq:NN\__skmath_Im:\Im
  \DeclareDocumentCommand\Im{m}{\ensuremath{\__skmath_Im:\__skmath_parens:n{#1}}}
}{
  \DeclareDocumentCommand\Im{m}{\ensuremath{{\operator@font Im}{#1}}}
}
\DeclarePairedDelimiter\abs{\lvert}{\rvert}
\DeclarePairedDelimiter\norm{\lVert}{\rVert}
\AtBeginDocument{
  \DeclareDocumentCommand\E{m}{%
    \ensuremath{\operatorname{E}\left[#1\right]}%
  }
}
\DeclareDocumentCommand\P{m}{%
  \ensuremath{\operatorname{P}%
    \mkern-1.5mu\left(%
    \cs_set_eq:NN\__skmath_saved_given:\given%
    \DeclareDocumentCommand\given{}{\mid}%
    #1%
    \cs_set_eq:NN\given\__skmath_saved_given:%
    \right)%
  }%
}
\DeclareDocumentCommand\var{m}{%
  \ensuremath{\operatorname{Var}\left(#1\right)}%
}
\DeclareDocumentCommand\cov{mm}{%
  \ensuremath{\operatorname{Cov}\left(#1,#2\right)}%
}
\cs_new_eq:NN\__skmath_sin:\sin
\cs_new_eq:NN\__skmath_cos:\cos
\cs_new_eq:NN\__skmath_tan:\tan
\cs_new_eq:NN\__skmath_cot:\cot
\cs_new_eq:NN\__skmath_arcsin:\arcsin
\cs_new_eq:NN\__skmath_arccos:\arccos
\cs_new_eq:NN\__skmath_arctan:\arctan
\cs_new_eq:NN\__skmath_sinh:\sinh
\cs_new_eq:NN\__skmath_cosh:\cosh
\cs_new_eq:NN\__skmath_tanh:\tanh
\cs_new_eq:NN\__skmath_ln:\ln
\cs_new_eq:NN\__skmath_log:\log
\cs_new_eq:NN\__skmath_exp:\exp
\cs_new_eq:NN\__skmath_min:\min
\cs_new_eq:NN\__skmath_max:\max
\cs_new_eq:NN\__skmath_sup:\sup
\cs_new_eq:NN\__skmath_inf:\inf
\RenewDocumentCommand\sin{om}{%
  \IfNoValueTF{#1}
    {\ensuremath{\__skmath_sin:\__skmath_parens:n{#2}}}
    {\ensuremath{\__skmath_sin:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}%
}
\RenewDocumentCommand\cos{om}{%
  \IfNoValueTF{#1}
    {\ensuremath{\__skmath_cos:\__skmath_parens:n{#2}}}
    {\ensuremath{\__skmath_cos:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}%
}
\RenewDocumentCommand\tan{om}{%
  \IfNoValueTF{#1}
    {\ensuremath{\__skmath_tan:\__skmath_parens:n{#2}}}
    {\ensuremath{\__skmath_tan:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}%
}
\RenewDocumentCommand\cot{om}{%
  \IfNoValueTF{#1}
    {\ensuremath{\__skmath_cot:\__skmath_parens:n{#2}}}
    {\ensuremath{\__skmath_cot:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}%
}
\RenewDocumentCommand\arcsin{m}{%
  \ensuremath{\__skmath_arcsin:\__skmath_parens:n{#1}}%
}
\RenewDocumentCommand\arccos{m}{%
  \ensuremath{\__skmath_arccos:\__skmath_parens:n{#1}}%
}
\RenewDocumentCommand\arctan{m}{%
  \ensuremath{\__skmath_arctan:\__skmath_parens:n{#1}}%
}
\RenewDocumentCommand\sinh{om}{%
  \IfNoValueTF{#1}
    {\ensuremath{\__skmath_sinh:\__skmath_parens:n{#2}}}
    {\ensuremath{\__skmath_sinh:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}%
}
\RenewDocumentCommand\cosh{om}{%
  \IfNoValueTF{#1}
    {\ensuremath{\__skmath_cosh:\__skmath_parens:n{#2}}}
    {\ensuremath{\__skmath_cosh:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}%
}
\RenewDocumentCommand\tanh{om}{%
  \IfNoValueTF{#1}
    {\ensuremath{\__skmath_tanh:\__skmath_parens:n{#2}}}
    {\ensuremath{\__skmath_tanh:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}%
}
\RenewDocumentCommand\ln{m}{%
  \ensuremath{\__skmath_ln:\__skmath_parens:n{#1}}%
}
\RenewDocumentCommand\log{om}{%
  \IfNoValueTF{#1}
    {\ensuremath{\__skmath_log:\__skmath_parens:n{#2}}}
    {\ensuremath{\__skmath_log:\c_math_subscript_token{#1}\__skmath_parens:n{#2}}}%
}
    \DeclareDocumentCommand\ee{}{\ensuremath{\__skmath_natural_log_e:}}
    
\RenewDocumentCommand\exp{sm}{\ensuremath{
  \IfBooleanTF{#1}{
    \__skmath_exp:\__skmath_parens:n{#2}
  }{
    \mathchoice
      {\__skmath_natural_log_e:\c_math_superscript_token{#2}}
      {\__skmath_exp:\left(#2\right)}
      {\__skmath_exp:\left(#2\right)}
      {\__skmath_exp:\left(#2\right)}
  }
}}
\cs_new_nopar:Npn\__skmath_minmax_backend:nnnn#1#2#3#4{%
  \use:c{__skmath_#1:}
  \IfNoValueF{#3}{
    \c_math_subscript_token{
      \mathchoice{\mathclap{#3}}{#3}{#3}{#3}
    }
  }
  \IfBooleanTF{#2}{#4}{\left\{#4\right\}}
}
\RenewDocumentCommand\min{som}{%
  \ensuremath{\__skmath_minmax_backend:nnnn{min}{#1}{#2}{#3}}
}
\NewDocumentCommand\argmin{som}{%
  \ensuremath{\arg\__skmath_minmax_backend:nnnn{min}{#1}{#2}{#3}}
}
\RenewDocumentCommand\max{som}{%
  \ensuremath{\__skmath_minmax_backend:nnnn{max}{#1}{#2}{#3}}
}
\NewDocumentCommand\argmax{som}{%
  \ensuremath{\arg\__skmath_minmax_backend:nnnn{max}{#1}{#2}{#3}}
}
\RenewDocumentCommand\sup{som}{%
  \ensuremath{\__skmath_minmax_backend:nnnn{sup}{#1}{#2}{#3}}
}
\RenewDocumentCommand\inf{som}{%
  \ensuremath{\__skmath_minmax_backend:nnnn{inf}{#1}{#2}{#3}}
}
\RenewDocumentCommand\frac{mm}{\genfrac{}{}{}{}%
             {\displaystyle #1}{\displaystyle #2}}
\prg_new_conditional:Npnn\__skmath_if_numerical:n#1{p,T,F,TF}{
  \str_case_x:nnTF{#1}{
    {0}{}
    {1}{}
    {2}{}
    {3}{}
    {4}{}
    {5}{}
    {6}{}
    {7}{}
    {8}{}
    {9}{}
  }
  {\prg_return_false:}
  {\prg_return_false:}
}
\cs_new_nopar:Npn\__skmath_pd_vars_sum:n#1{
  \tl_clear:N\l_tmpa_tl
  \int_zero:N\l_tmpa_int
  \bool_set_true:N\l_tmpa_bool
  \clist_set:Nn\l_tmpa_clist{#1}
  \clist_map_inline:Nn\l_tmpa_clist{
    \seq_set_split:Nnn\l_tmpa_seq{^}{##1}
    \int_compare:nT{\seq_count:N\l_tmpa_seq<\c_two}{
      \seq_put_right:Nn\l_tmpa_seq{1}
    }
    \seq_get_right:NN\l_tmpa_seq\l_tmpb_tl
    \__skmath_if_numerical:nTF{\tl_use:N\l_tmpb_tl}{
      \int_add:Nn\l_tmpa_int{\tl_use:N\l_tmpb_tl}
    }{
      \bool_set_false:N\l_tmpa_bool
      \tl_if_empty:NF\l_tmpa_tl{\tl_put_right:Nn\l_tmpa_tl{+}}
      \tl_put_right:Nx\l_tmpa_tl{\tl_use:N\l_tmpb_tl}
    }
  }
  \int_compare:nT{\l_tmpa_int>\c_zero}{\int_use:N\l_tmpa_int}
  \bool_if:NF\l_tmpa_bool{
    \int_compare:nT{\l_tmpa_int>\c_zero}{+}
    \tl_use:N\l_tmpa_tl
  }
}
\prg_new_conditional:Npnn\__skmath_pd_if_vars_sum_above_one:n#1{p,T,F,TF}{
  \clist_set:Nn\l_tmpa_clist{#1}
  \int_compare:nTF{\clist_count:N\l_tmpa_clist>\c_one}{
    \prg_return_true:
  }{
    \clist_pop:NN\l_tmpa_clist\l_tmpa_tl
    \seq_set_split:NnV\l_tmpa_seq{^}{\l_tmpa_tl}
    \int_compare:nTF{\seq_count:N\l_tmpa_seq<\c_two}{
      \prg_return_false:
    }{
      \prg_return_true:
    }
  }
}
\cs_new_nopar:Npn\__skmath_pd_superscript_vars:n#1{
  \clist_set:Nn\l_tmpa_clist{#1}
  \clist_map_inline:Nn\l_tmpa_clist{
    \partial
    \seq_set_split:Nnn\l_tmpa_seq{^}{##1}
    \seq_pop:NN\l_tmpa_seq\l_tmpb_tl
    \tl_use:N\l_tmpb_tl
    \int_compare:nT{\seq_count:N\l_tmpa_seq>0}{
      \seq_pop:NN\l_tmpa_seq\l_tmpb_tl
      \c_math_superscript_token
      \tl_use:N\l_tmpb_tl
    }
  }
}
\cs_new_nopar:Npn\__skmath_pd_subscript_vars:n#1{
  \clist_set:Nn\l_tmpa_clist{#1}
  \clist_map_inline:Nn\l_tmpa_clist{
    \seq_set_split:Nnn\l_tmpa_seq{^}{##1}
    \seq_pop:NN\l_tmpa_seq\l_tmpa_tl
    \int_set:Nn\l_tmpa_int{\c_one}
    \int_compare:nT{\seq_count:N\l_tmpa_seq>\c_zero}{
      \seq_pop:NN\l_tmpa_seq\l_tmpb_tl
      \int_set:Nn\l_tmpa_int{\tl_use:N\l_tmpb_tl}
    }
    \prg_replicate:nn{\l_tmpa_int}{\tl_use:N\l_tmpa_tl}
  }
}
\cs_new_nopar:Npn\__skmath_pd_fraction:nn#1#2{
  \frac{
    \partial
    \__skmath_pd_if_vars_sum_above_one:nT{#2}{
      \c_math_superscript_token{\__skmath_pd_vars_sum:n{#2}}
    }
    {#1}
  }{
    \__skmath_pd_superscript_vars:n{#2}
  }
}
\cs_new_nopar:Npn\__skmath_pd_subscript:nn#1#2{
  {#1}\c_math_subscript_token{
    \__skmath_pd_subscript_vars:n{#2}
  }
}
\cs_new_nopar:Npn\__skmath_td_fraction:nn#1#2{
  \frac{
    \__skmath_total_derivative_d:
    \__skmath_pd_if_vars_sum_above_one:nT{#2}{
      \c_math_superscript_token{\__skmath_pd_vars_sum:n{#2}}
    }
    {#1}
  }{
    \__skmath_total_derivative_d:
    #2
  }
}
\AtBeginDocument{%
\DeclareDocumentCommand\bar{m}{%
    \ensuremath{\mkern 1.5mu\overline{\mkern-1.5mu{#1}\mkern-1.5mu}\mkern 1.5mu}}
\DeclareDocumentCommand\pd{smm}{
  \ensuremath{
    \IfBooleanTF{#1}
      {\__skmath_pd_subscript:nn{#2}{#3}}
      {\__skmath_pd_fraction:nn{#2}{#3}}
  }
}
\DeclareDocumentCommand\td{mm}{
  \ensuremath{
    \__skmath_td_fraction:nn{#1}{#2}
  }
}
\DeclareDocumentCommand\d{m}{\ensuremath{\,\__skmath_integral_d: #1%
                              \peek_meaning_ignore_spaces:NT\d{\!}}}
}
\cs_set_eq:NN\vec\vectorsym
\endinput

