Why Does sym(cell) Not Return a Cell?

As far as I can tell, there is no documented behavior for calling sym with single input that's a cell. Nevertheless, if doing so doesn't result in an error, then I'd expect it to return a cell, but it doesn't.
syms a
c = {a,a}
c = 1×2 cell array
{[a]} {[a]}
h = sym(c), iscell(h)
h = 
ans = logical
0
c = {pi,sqrt(2)}
c = 1×2 cell array
{[3.1416]} {[1.4142]}
h = sym(c),iscell(h)
h = 
ans = logical
0
I guess I would expect sym(c) to be shorthand for
h = cellfun(@(c) sym(c),c,'Uni',false)
h = 1×2 cell array
{[pi]} {[2^(1/2)]}
iscell(h)
ans = logical
1

5 Comments

Answer from AI:
A symbolic object itself is not a cell array, but you can store symbolic objects inside a standard MATLAB cell array, or convert between cell arrays and symbolic arrays. [1, 2, 3]
Key Facts
  • Data Types: A symbolic object (sym or symfun) has its own distinct class and is not a cell array by default. [1]
  • Storage: You can place multiple symbolic variables, expressions, or mixed symbolic functions into a cell array using curly braces {}. This is required if you want an array of different symbolic functions, because regular parentheses () indexing on symbolic functions triggers function evaluation rather than indexing. [1]
  • Conversion Functions:
  • Use cell2sym to convert a cell array containing valid elements into a symbolic array.
  • Use sym2cell to convert a symbolic array into a standard cell array. [1, 2]
Nevertheless, if doing so doesn't result in an error, then I'd expect it to return a cell, but it doesn't.
Why would you expect that?
c = {'apple', 'banana'}
c = 1×2 cell array
{'apple'} {'banana'}
s = string(c)
s = 1×2 string array
"apple" "banana"
Should s be a cell array? No, it shouldn't. Now if a class defines a cell conversion method that could work. But not a lot of classes define such a conversion method. Usually users want to contain an object or array in a cell rather than converting an object or array into a cell, and for that you want to use the {} operator or perhaps mat2cell or num2cell.
c2 = {s}
c2 = 1×1 cell array
{["apple" "banana"]}
c3 = mat2cell(s, 1, [1 1])
c3 = 1×2 cell array
{["apple"]} {["banana"]}
c4 = num2cell(s)
c4 = 1×2 cell array
{["apple"]} {["banana"]}
Hi Steven,
I don't find the comparison with string/cell compelling because the usage string(cell) is documented (and makes sense based on the historical usage of "cellstr" arrays. Given that sym(cell) is not documented (as far as I can tell), and, as you say, there aren't a lot of (any besides string?) classes that define a cell conversion method, then what should the user expect from sym(cell) (but see my response below to @dpb).
Why isn't the usage sym(cell) documented? Is that one of those thing that Mathworks takes advantage of in their own code but users shouldn't because the behavior may change?
Is there any difference when converting from cell to sym using sym versus the documented cell2sym?
I'm not 100% certain (I'd have to go back and check) but I suspect the sym(cell) syntax was introduced in order to allow creating a vector of symbolic variables in one call. Back before string arrays were introduced, in order to store two or more pieces of text data in one variable you had two options: a char matrix or a cell array each element of which is a char vector (commonly called a cellstr, see the cellstr and iscellstr functions).
dataChar = ['apple '; 'banana'] % Note the space after apple
dataChar = 2×6 char array
'apple ' 'banana'
dataCell = cellstr(dataChar)
dataCell = 2×1 cell array
{'apple' } {'banana'}
Passing either dataChar or dataCell into sym creates a 2-by-1 sym array, as a generalization of the sym("x") and sym(symnum) syntaxes listed in the documentation.
sChar = sym(dataChar)
sChar = 
sCell = sym(dataCell)
sCell = 
whos sChar sCell
Name Size Bytes Class Attributes sCell 2x1 8 sym sChar 2x1 8 sym
Though today, since string arrays exist, we strongly recommend using those instead of char matrices (which require padding the char vectors with spaces to make them the same length) or cellstrs. See this documentation page for more information.
Iit appears it's an undocumented feature for backwards compatibility using modern syntax internally,
dbtype sym 1279:1281
1279 function S = tomupad(x) 1280 %TOMUPAD Convert input to sym reference string 1281 % Called by sym constructor to take 'x' (just about anything) and return the reference string S.
...code for handling other classes of input not shown for brevity... dpb
dbtype sym 1310:1316
1310 elseif iscell(x) 1311 % undocumented syntax, still allowed for compatibility reasons 1312 xsym = cell2sym(x); 1313 S = evalin2charAns(symengine, xsym.s); % make a new reference 1314 else 1315 error(message('symbolic:sym:sym:errmsg7', class( x ))) 1316 end

Sign in to comment.

 Accepted Answer

If I recall correctly, historically it had to do with the way that arguments used to be constructed for the internal conversion routine.
syms a
[a, 1]
was not treated as
arrayfun(@sym, {a, 1})
and instead the entries were converted to character vectors before being passed into an feval(symengine) routine
Along the way, some intermediate forms could sometimes introduce {} where {} was not explicit, and because of that sym() of a cell had to return a sym vector.

5 Comments

Did you mean curly braces or square brackets in that arrayfun call?
Regardless, do you know if this behavior is still needed given how Matlab and Symbolic Math Toolbox work today? I'm sure it won't ever change, so just asking out of idle curiosity.
dpb
dpb on 7 Sep 2026 at 16:44
Edited: dpb on 7 Sep 2026 at 21:14
I have never used and don't have the symbolic TB, but I don't see why one would ever expect
h = sym(ANYTHING), iscell(h)
to return TRUE; and
class(h)
not return the class of sym?
All of those examples look to my eye as either explicitly creating a cell array or a symbolic variable, depending on the specific case.
Is there some deep mystery buried here that isn't straightforward to the casual observer I'm just not seeing? (And, yes, it's a slow hot Labor Day with nothing much else going on... :>) )
dpb
dpb on 7 Sep 2026 at 17:56
Edited: dpb on 7 Sep 2026 at 18:50
a=1;
arrayfun(@sym, {a, 1})
ans = 
arrayfun(@sym, [a, 1])
ans = 
arrayfun(@disp, {a, 1})
{[1]} {[1]}
arrayfun(@disp, [a, 1])
1 1
arrayfun passes the array as individual elements either way; sym is built to treat either the same if appears.
Paul
Paul on 7 Sep 2026 at 20:29
Edited: Paul on 7 Sep 2026 at 20:40
" why one would ever expect ...
h = sym(ANYTHING) ...
[to] not return ... sym?" (or an error)
That's a very good way to think about it. Makes sense to return a sym.
I wonder why sym(cell) is undocumented.
I did mean {} in the arrayfun call, but I meant to write a cellfun call instead of arrayfun.

Sign in to comment.

More Answers (0)

Products

Release

R2026a

Asked:

on 6 Sep 2026 at 20:12

Commented:

dpb
on 8 Sep 2026 at 14:39

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!