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?

4

3 Answers 3

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .