11

In order to separate the content structure from the style, I decided to implement commands for denoting random variables:

\newcommand{\myrv}[1]{\mathbf{#1}}
\newcommand{\rvA}{\myrv{A}}
\newcommand{\rvB}{\myrv{B}}
\newcommand{\rvC}{\myrv{C}}
...

This way, if I ever decide to change the style of random variables from \mathbf to say \mathbb, all I need to do is to change the definition of \myrv. Is a way to generate the commands \rvA, \rvB, \rvC, ... automatically?

5

There are other similar questions, but none that treats explicitly this problem, as far as I can see.

\documentclass{article}

\makeatletter
\newcommand{\generate}[4]{%
  %#1 = prefix, #2 = macro, #3 = starting point, #4 = end point
  \def\@tempa{#1} % we don't want to lowercase it
  \count@=`#3
  \loop
  \begingroup\lccode`?=\count@
  \lowercase{\endgroup\@namedef{\@tempa ?}{#2{?}}}%
  \ifnum\count@<`#4
  \advance\count@\@ne
  \repeat
}

\generate{rv}{\mathbf}{A}{Z}
\show\rvA
\show\rvZ
\generate{rv}{\mathbf}{a}{z}
\show\rva
\show\rvz

The \show command are just to see that it worked. The terminal output is

> \rvA=macro:
->\mathbf {A}.
l.17 \show\rvA

? 
> \rvZ=macro:
->\mathbf {Z}.
l.18 \show\rvZ

? 
> \rva=macro:
->\mathbf {a}.
l.20 \show\rva

? 
> \rvb=macro:
->\mathbf {b}.
l.21 \show\rvb

An extended version using expl3:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\generate}{ m m m m }
 {
  \iliketocode_generate:nnnn { #1 } { #2 } { #3 } { #4 }
 }

\cs_new_protected:Nn \iliketocode_generate:nnnn
 {
  \cs_set:Nn \__iliketocode_generate_name:n { #3 }
  \cs_set:Nn \__iliketocode_generate_wrapper:n { \exp_not:n { #4 } }
  \int_step_inline:nnnn { `#1 } { 1 } { `#2 }
   {
    \cs_new:cpx
     {
      \__iliketocode_generate_name:n { \char_generate:nn { ##1 } { 11 } }
     }
     {
      \exp_args:Nf \__iliketocode_generate_wrapper:n { \char_generate:nn { ##1 } { 11 } }
     }
   }
 }
\ExplSyntaxOff

\generate{A}{Z}{rv#1}{\mathbf{#1}}
\show\rvA
\show\rvZ
\generate{a}{z}{rv#1}{\mathbf{#1}}
\show\rva
\show\rvz
\generate{A}{Z}{#1cal}{\mathcal{#1}}
\show\Acal
\show\Zcal
\generate{A}{Z}{#1#1#1}{\mathrm{#1}}
\show\RRR
\show\PPP

The syntax of \generate is a bit different: the first argument is the starting point, the second argument is the end point; the third argument is the format for the name and the fourth argument is the format for the required definition, where #1 stands for the current letter in the cycle.

The examples should make their meanings clear.

Here's the output on the terminal, just for checking.

> \rvA=\long macro:
->\mathbf {A}.

> \rvZ=\long macro:
->\mathbf {Z}.

> \rva=\long macro:
->\mathbf {a}.

> \rvz=\long macro:
->\mathbf {z}.

> \Acal=\long macro:
->\mathcal {A}.

> \Zcal=\long macro:
->\mathcal {Z}.

> \RRR=\long macro:
->\mathrm {R}.

> \PPP=\long macro:
->\mathrm {P}.
6

You could define a macro that takes a list of names and creates the corresponding macros:

\documentclass{article}

\newcommand{\myrv}[1]{\mathbf{#1}}

\makeatletter
\newcommand*\defrvar[1]{
  \expandafter\newcommand\csname rv#1\endcsname[1][]{\myrv{#1}}}

\newcommand*\defrvars[1]{
  \@for\@i:=#1\do{\expandafter\defrvar\expandafter{\@i}}}
\makeatother


\defrvars{a,b,c} % this defines \rva, \rvb and \rvc

\begin{document}

Hi $\rva, \rvb + \rvc$
\end{document}
1
\newcommand{\myrv}[1]{\mathbf{#1}}
\newcommand{\makerv}[1]{%
  \expandafter\newcommand\csname rv#1\endcsname{\myrv{#1}}%
}

\newcommand{\defAllRv}[1]{%
  \ifx#1\deffAllRv%
  \else%
      \makerv{#1}\expandafter\mydefallb%
  \fi}
\deffAllRv abcdefghijklmnopqrstuvwxyz\defAllRv

this code define all \rva...\rvz. it's basend on : Difference between \if and \ifx and Defining a newcommand, with variable name, inside another newcommand

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.