Loren on the Art of MATLAB

Turn ideas into MATLAB


Loren on the Art of MATLAB has been archived and will not be updated.

Compose Yourself!

Even if we crunch numbers a lot, there are plenty of times, for example, when reporting, that we need to mix numbers into text. For a very long time, we've been able to create a character vector, and more recently, a string, with functions like sprintf. Look here for more information on character arrays and strings.

That's fine if we want to create one textual entity, but what if I need an array of them? I can use sprintf in a loop, or I can use a newer function, compose. Let me show you a bit how they each work.


A Single Numeric Input

Let's create some numeric values to use as possible inputs.

nums = [exp(1) pi]
nums =
    2.7183    3.1416

Here's character output from sprintf:

cs1 = sprintf('%d', nums(2))
cs1 =

And here's the equivalent string output:

ss1 = sprintf("%d", nums(2))
ss1 = 

Now let's try compose:

cc1 = compose('%d', nums(2))
cc1 =
  1×1 cell array
sc1 = compose("%d", nums(2))
% What do we have in our workspace?
sc1 = 
  Name      Size            Bytes  Class     Attributes

  ans       1x4                 8  char                
  cc1       1x1               136  cell                
  ccm1      1x2               272  cell                
  cs1       1x12               24  char                
  csm1      1x26               52  char                
  nums      1x2                16  double              
  sc1       1x1               174  string              
  scm1      1x2               252  string              
  ss1       1x1               174  string              
  ssm1      1x1               206  string              
  tc        1x1               120  cell                
  tmpc      1x2               228  cell                
  tmps      1x2                 4  char                
  ts        1x2                 4  char                

What you may notice is that both sprintf and compose give the same output for the string version. However, for the character output, we get one character array using sprintf, but that same array embedded in a cell using compose.

clearvars -except nums

Multiple Numeric Inputs

Now let's see what happens if we are formatting output with more than a single numeric input.

csm1 = sprintf('%d ',nums)
ssm1 = sprintf("%d ",nums)
ccm1 = compose('%d',nums)
scm1 = compose("%d",nums)
csm1 =
    '2.718282e+00 3.141593e+00 '
ssm1 = 
    "2.718282e+00 3.141593e+00 "
ccm1 =
  1×2 cell array
    {'2.718282e+00'}    {'3.141593e+00'}
scm1 = 
  1×2 string array
    "2.718282e+00"    "3.141593e+00"
  Name      Size            Bytes  Class     Attributes

  ccm1      1x2               272  cell                
  csm1      1x26               52  char                
  nums      1x2                16  double              
  scm1      1x2               252  string              
  ssm1      1x1               206  string              

What we see is that we get exactly the same types of output as before. But for the string version with compose, we get output matching the dimensions of the input, in this case, 1x2, whereas with the sprintf version, we get a single array for all of the cases. sprintf always produces a single array as output and recycles the hole (the formatter) while there is more data to format. compose returns arrays of text.

Handling Holes

Again, sprintf produces one output, regardless of the dimensions of the input.

tmps = sprintf('%d',[1 2])
tmpc = compose('%d',[1 2])
tmps =
tmpc =
  1×2 cell array
    {'1'}    {'2'}

Also, sprintf truncates a hole if you don’t provide data. compose leaves it there in case you want to fill it with a subsequent call:

ts = sprintf('\n %s')

tc = compose('\n %s')
ts =
tc =
  1×1 cell array
    {'↵ %s'}

Your Turn

Do you need to format text/numbers? What techniques do you use to get the results you want? Let us know here.

Published with MATLAB® R2019a

  • print


To leave a comment, please click here to sign in to your MathWorks Account or create a new one.