# Identify a scalar, a list

I have a symbolic scalar m2 and a symbolic list (representing a 3x3 matrix) A. I want a function which does something like:

In= function[m2]==Scalar
Out= True
In= function[m2]==List
Out= False

In= function[A]==Scalar
Out= False
In= function[A]==List
Out= True


So far I tried doing:

In= Assuming[Element[m2, Reals], Head[m2]]
Out= Symbol


Out is not what I want! Thank you for you help.

• check out MatrixQ
– chuy
Commented Jul 23, 2015 at 20:30
• This sounds like a weird request. I wonder if maybe you might be asking the wrong question. What is the underlying problem you are trying to solve here? Commented Jul 23, 2015 at 20:33
• I have a list of symbolic variables {m2,A,B,C,x,gamma} for example. I need to go through the list and identify which are scalars, which are matrices (lists). In $Assumptions I indicated that Element[m2|x|gamma,Reals] and Element[A|B|C,Matrices[{3,3}]]. For @chuy MatrixQ does not work, Assuming[Element[A, Matrices[{3, 3}]], MatrixQ[A]] gives back False. Commented Jul 23, 2015 at 20:37 • See, that's where I think the misunderstanding might lie: such a functionality doesn't exist because it is typically not needed. Why do you need to know whether a variable is a scalar or a matrix? What will you do with that knowledge? Commented Jul 23, 2015 at 20:52 • @MarcoB I need it because I have to do convert an symbolic algebraic expression into (vector transposed)*(matrix)*(vector). Sometimes a term in the (matrix) will be a scalar, in which case I need to multiply it by a 3x3 identity matrix. I thus need to find out when a term is just a scalar. Commented Jul 23, 2015 at 20:57 ## 3 Answers If you just want to track things for your own usage you could do something simple like this: lists = {a, b, c}; scalars = {p, q, r}; function[sym_] := Which[ MemberQ[lists, sym], "list", MemberQ[scalars, sym], "scalar", True, Head[sym]] function /@ {a, p, 0}  {"list", "scalar", Integer} You could try working with this... $Assumptions = {Element[a | b | c, Matrices[{3, 3}]], Element[p | q, foo]}

TrueQ@Simplify[Element[a, Matrices[{3, 3}]]]
TrueQ@Simplify[Element[r, Matrices[{3, 3}]]]
TrueQ@Simplify[Element[p, foo]]
TrueQ@Simplify[Element[r, foo]]


True False True False

That seems like it might be at least confusing, as you know intrinsics like MatrixQ,NumberQ, etc wont make use of it.

• I'd be careful about using C, since it's a built in symbol (docs). Commented Jul 23, 2015 at 20:55
• good call, shouldnt have used CAPS at all.. Commented Jul 23, 2015 at 20:59

If you think you will run into that ambiguity a lot you might want to define a function to carry out your calculation:

Clear[matrixmult]
matrixmult[m_?MatrixQ, v_?VectorQ] := v.m.v
matrixmult[m_?NumberQ, v_?VectorQ] := v.(m IdentityMatrix[3]).v


I used two conditional definitions: the correct definitions will be picked depending on the type of the arguments with which it is called.

So then as an example:

SeedRandom[1]
num = RandomReal[];
mat = RandomReal[1, {3, 3}];
vec = RandomReal[1, 3];

matrixmult[num, vec]
matrixmult[mat, vec]

(*Out:
0.640964
0.665124
*)

• I don't know if the OP noticed, but in fact, m v.v suffices in the scalar case. Commented Jul 23, 2015 at 23:45
• I think this misses the point, as I understand he is working with symbols that have not actually been defined as lists/matrices. @SpaceVoyager might want to supply some example to clarify. Commented Jul 24, 2015 at 14:35

## The Need

I found a solution for the problem, but first since people here asked why would there be a need I'll elaborate about my need.

In my case I defined and inner product which is supposed to act both on vectors and scalars (scalars are just vectors with unit length). Since I wanted the definition to be general for other cases as well, I didn't want to have separate definition for vectors and scalars.

I defined it using Inner for the "vector" case. However, when trying to use it on scalars I got:

Inner::normal: Nonatomic expression expected at position 2 in Inner

## The Concept

It seems that ArrayDepth is able to discern the depth of an object quite well, except for one case when there's a scalar value, which contains arithmetic such as 1+x. In such a case we get the same result as for a vector, or even for an ill defined object:

ArrayDepth[1]
ArrayDepth[x + Sqrt[2 + v]]
ArrayDepth[{1 + v, 1}]
ArrayDepth[{{1}, {1, 2}}]

(*Out:
0
1
1
1
*)


We get the same result for the scalar and the vector. However this case can easily be dealt with, because ListQ can recognize the scalars correctly:

ListQ[1]
ListQ[x + Sqrt[2 + v]]
ListQ[{1 + v, 1}]
ListQ[{{1}, {1, 2}}]

(*Out:
False
False
True
True
*)


## The Solution

Hence we can define two functions as a solution. The first lighter solution will be to define a ScalarQ function of our own:

ScalarQ[object_] := (! ListQ[object] && ArrayDepth[object] == 1) || ArrayDepth[object] == 0


This solution gives this:

ScalarQ[1]
ScalarQ[x + Sqrt[2 + v]]
ScalarQ[{1 + v, 1}]
ScalarQ[{{1}, {1, 2}}]


True

True

False

False

The second solution will generally identify math objects:

MathDimensions::unknown_dimensions = "There was a problem evaluating 1 dimensions."
MathDimensions[object_] := Which[
Length[Dimensions[object]] >= 3, "Higher Order Tensor",
MatrixQ[object], "Matrix",
VectorQ[object], "Vector",
(! ListQ[object] && ArrayDepth[object] == 1) || ArrayDepth[object] == 0, "Scalar",
True, Message[MathDimensions::unknown_dimensions, object]; "None"
]


Which will give us:

MathDimensions[1]
MathDimensions[x + Sqrt[2 + v]]
MathDimensions[{1 + v, 1}]
MathDimensions[{{1, 2}, {3, 4}}]
MathDimensions[{{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}}]
MathDimensions[{{1}, {1, 2}}]


Scalar

Scalar

Vector

Matrix

Higher Order Tensor

MathDimensions::unknown_dimensions: There was a problem evaluating {{1},{1,2}} dimensions.

None