5

The following is to construct illustrations for concepts of frequency of a properly sampled outcome if any such frequency exists. Doing such illustrations is tedious and liable to error by hand ... so it's best to make a pair of macros and make a macro out of them that does the following:

Suppose I have a block of text with, say, 2 or more arbitrary letters or numbers,

axaaxxaaaxxaaaxxaaaaxxaxa

How does one make a macro that splits a line of text according to the following rule:

If the parameter to the macro is 2, take every second letter in each pair and juxtapose them. That is line 2. Delete these letters from the original line and the remainder is line 1. Display all 2 lines.

If the parameter to the macro is 3, take every second letter in each triple and juxtapose them. This is line 2. Take every third letter in each triple and juxtapose them. That is line 3. Delete these letters from the original line and the remainder is line 1. Display all 3 lines.

If I write

\brk{+}{1}{axaaxxaaaxxaaaxxaaaaxxaxa}

the equivalent manual code is

\begin{equation}
    \textrm{axaaxxaaaxxaaaxxaaaaxxaxa}
\end{equation}

If I write

\brk{+}{2}{axaaxxaaaxxaaaxxaaaaxxaxa}

the equivalent manual code is

\begin{equation}
    \textrm{aaxaaxaxaaxaa}
\end{equation}
\begin{equation}
    \textrm{xaxaxaaxaaxx}
\end{equation}

If I write

\brk{+}{3}{axaaxxaaaxxaaaxxaaaaxxaxa}

the equivalent manual code is

\begin{equation}
    \textrm{aaaxaxaxa}
\end{equation}
\begin{equation}
    \textrm{aaaxaxaxa}
\end{equation}
\begin{equation}
    \textrm{axxaxaaaa}
\end{equation}

And so on.

Now the - parameter chooses the second version of the macro and reverse this behavior.

If I write

\brk{-}{1}{axaaxxaaaxxaaaxxaaaaxxaxa}

the equivalent manual code is

\begin{equation}
    \textrm{axaaxxaaaxxaaaxxaaaaxxaxa}
\end{equation}

If I write

\brk{-}{2}{aaxaaxaxaaxaa}{xaxaxaaxaaxx}

the equivalent manual code is

\begin{equation}
    \textrm{axaaxxaaaxxaaaxxaaaaxxaxa}
\end{equation}

If I write

\brk{-}{3}{aaaxaxaxa}{aaaxaxaxa}{axxaxaaaa}

the equivalent manual code is

\begin{equation}
    \textrm{axaaxxaaaxxaaaxxaaaaxxaxa}
\end{equation}

And so on.

Yes, the ability to format the results into a specific environment for instance the equation environment or change the font or vertical spacing of the n lines in \{brk{+/-}{n}{axaaxxaaaxxaaaxxaaaaxxaxa is important as this is for figure purposes. Hopefully there is a way to make it not a problem for the macro.

BTW the result is this: if the strings are long enough and tending to a frequency of, say, x is 1/3 (iff the original string was randomly sampled as it must be for most scientific purposes) then in each of the two or three or more string made from it by any rule of thumb, the frequency of x is also tending to be 1/3 rather quickly. And if we sampled three parts of the same population each tending to a frequency of x being 1/3 and then added the strings together according to any systematic rule, the frequency of x tends again to 1/3.

  • In other words you want to transpose a matrix. ;-) – egreg Jul 11 '14 at 9:45
  • I'm sorry: as I understood your rules, I don't obtain the same results. E;g., for \brk{+}{2} I have the word xaxaxaax. There's not even the same number of letters! – Bernard Jul 11 '14 at 9:48
  • This is exactly why I wanted to do it automatically ;) Doing it by hand one easily makes an error following the rules defined for each letter. See the posted answers below, they did it. – Guido Jorg Jul 11 '14 at 15:35
7

If I understand your wish, you need to use the following macros:

\newcount\tmpnum
\def\sedef#1{\expandafter\edef\csname#1\endcsname}
\def\expandcsname#1{\expandafter\ifx\csname#1\endcsname\relax \else \csname#1\endcsname\fi}

\def\brk#1#2#3{\bgroup\def\brkLines{#2}\ifx+#1\tmpnum=0 \brkA#3{}%
   \else\tmpnum=1 \def\brkF{}\def\tmp{\brkC{#3}}\expandafter\tmp\fi
}
\def\brkA#1{\ifx$#1$\expandafter\brkB\else 
   \advance\tmpnum by1   
   \ifnum\tmpnum>\brkLines \tmpnum=1 \fi
   \sedef{brk:\the\tmpnum}{\expandcsname{brk:\the\tmpnum}#1}%
   \expandafter\brkA \fi
}
\def\brkB{\tmpnum=0
   \loop
      \advance\tmpnum by1
      $$\hbox{\csname brk:\the\tmpnum\endcsname}$$
      \ifnum\tmpnum<\brkLines\relax \repeat
   \egroup
}
\def\brkC #1{%
   \sedef{brk:\the\tmpnum}{#1}%
   \ifnum\tmpnum<\brkLines\relax \advance\tmpnum by1 \expandafter\brkC
   \else \expandafter\brkD \fi
}
\def\brkD{\tmpnum=0
   \loop
      \advance\tmpnum by1
      \ifnum\tmpnum>\brkLines \tmpnum=1 \fi
      \expandafter\ifx\csname brk:\the\tmpnum\endcsname \empty \tmpnum=0
      \else
         \edef\tmp{\csname brk:\the\tmpnum\endcsname}%
         \expandafter \brkE \tmp \brkF
      \fi 
      \ifnum\tmpnum>0 \repeat
   $$\hbox{\brkF}$$
   \egroup
}
\def\brkE#1#2\brkF{\edef\brkF{\brkF#1}\sedef{brk:\the\tmpnum}{#2}}


\brk{+}{3}{123abcuvw} % --> 1au // 2bv // 3cw

\brk{-}{3}{123}{abc}{uvw}  % --> 1au2bc3cw

\brk{+}{3}{axaaxxaaaxxaaaxxaaaaxxaxa}

\brk{-}{3}{aaaxaxaxa}{aaaxaxaxa}{axxaxaaaa}

A short summary, how it works. The \brk macro executes \brkA if the parameter is + (break to more lines) and executes \brkC if the parameter is - (merge to one line).

The \brkA reads token per token from input stream in the loop and appends it to macros \brk:num where num is 1,2,3,...,\brkLines, 1,2,3,...,\brkLines,...etc. The \brkA ends by executing \brkB: it prints contents of \brk:num macros from one to \brkLines in the display lines.

The inverse processing is done by \brkC which stores the n parameters (n=\brkLines) to the macros \brk:num and executes \brkD. This macro executes the loop where it reads and removes first token from \brk:num, where num is 1,2,3,...,\brkLines,1,2,3,...,\brkLines,etc. until first such macro is emty. The read tokens are accumulated to \brkF by help of \brkE. Finally the \brkF is printed in the display line.

  • This is great! One question: how to do I get the results numbered as equations? I mean, where in the code do I begin and end the equation group (and so on, for other commands, if I want to modify the formatting of the resulting text)? Also, where do I place a command to add or remove whitespace inside the displayed results? Adding commands I know in the macro in the usual places caused to to fail compiling? Otherwise it is very robust and requires no packages so perfect for journal papers. – Guido Jorg Jul 12 '14 at 4:10
  • 1
    @GuidoJorg You can replace $$\hbox{...}$$ by LaTeX commands \begin{equation} \textrm{...} \end{equation}. You can add the equation numbers and labels by LaTeX way here. You can use \label{foo:\the\tmpnum} and do \ref{foo:1}, \ref{foo:2}` etc. – wipet Jul 12 '14 at 4:28
  • Perfect. Works great. – Guido Jorg Jul 12 '14 at 4:29
3

Here's an application of expl3: for splitting I cycle the requested number of times through the input string, picking up the items corresponding to the cycle and forming a sequence; for rebuilding it's just the reverse: I cycle over the sequence elements picking up the first element, the second one and so on from each item.

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\breakstring}{mm}
 {
  \guido_breakstring:nn {#1} {#2}
 }
\NewDocumentCommand{\rebuildstring}{m}
 {
  \guido_rebuildstring:n { #1 }
 }

\int_new:N \l_guido_columns_int
\seq_new:N \l_guido_strings_seq
\tl_new:N \l_guido_temp_tl

\cs_new_protected:Npn \guido_breakstring:nn #1 #2
 {
  \seq_clear:N \l_guido_strings_seq
  \int_step_inline:nnnn { 1 } { 1 } { #1 }
   {
    \int_zero:N \l_guido_columns_int
    \tl_clear:N \l_guido_temp_tl
    \tl_map_inline:nn { #2 }
     {
      \int_incr:N \l_guido_columns_int
      \int_compare:nT { \l_guido_columns_int == ##1 }
       {
        \tl_put_right:Nn \l_guido_temp_tl { \mathrm{####1} }
       }
      \int_compare:nT { \l_guido_columns_int == #1 }
       { \int_zero:N \l_guido_columns_int }
     }
    \seq_put_right:NV \l_guido_strings_seq \l_guido_temp_tl
   }
  \begin{gather*}
  \seq_use:Nn \l_guido_strings_seq { \\ }
  \end{gather*}
 }

\cs_new_protected:Npn \guido_rebuildstring:n #1
 {
  \seq_set_split:Nnn \l_guido_strings_seq { ; } { #1 }
  \tl_set:Nx \l_guido_temp_tl { \seq_item:Nn \l_guido_strings_seq { 1 } }
  \int_set:Nn \l_guido_columns_int { \tl_count:N \l_guido_temp_tl }
  \tl_clear:N \l_guido_temp_tl
  \int_step_inline:nnnn { 1 } { 1 } { \l_guido_columns_int }
   {
    \seq_map_inline:Nn \l_guido_strings_seq
     {
      \tl_put_right:Nx \l_guido_temp_tl { \exp_not:N \mathrm{ \tl_item:nn { ####1 } { ##1 } } }
     }
   }
  \begin{equation*}
  \tl_use:N \l_guido_temp_tl { \\ }
  \end{equation*}
 }

\ExplSyntaxOff

\begin{document}
\breakstring{3}{12312312312}

\rebuildstring{1111;2222;333}

\section{Split}

One:
\breakstring{1}{axaaxxaaaxxaaaxxaaaaxxaxa}
Two:
\breakstring{2}{axaaxxaaaxxaaaxxaaaaxxaxa}
Three:
\breakstring{3}{axaaxxaaaxxaaaxxaaaaxxaxa}

\section{Rebuild}

One:
\rebuildstring{axaaxxaaaxxaaaxxaaaaxxaxa}
Two:
\rebuildstring{aaxaaxaxaaxaa;xaxaxaaxaaxx}
Three:
\rebuildstring{aaaxaxaxa;xxaxaaaa;axaaxaxx}

\end{document}

enter image description here

  • I hope you don't mind if I accept the other solution, since it works better for my other uses in the paper. I think this is also a good solution to study, since it generates the result in a neat way. – Guido Jorg Jul 12 '14 at 4:18

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.