# Assuming reals of unknown variables in a Matrix valued function

I am trying to write a generic matrix valued function in a package, of the form:

f[matrix_] := Module[...]


My problem is that I want to accept any matrix, but always assume that the functions/variables contained within the matrix are real. I realise that I can set assumptions when doing calculations, but for this it seems that I need to know the functions or variables before hand in order to set the assumptions up. How can I tell mathematica that any element of the matrix should be assumed to be real?

For clarification, lets say I do f[{{x,x^2},{h[x],S[y]^2}}]. I want mathematica to assume that x, x^2, h[x] and S[y] are all functions only involving real numbers, so I don't get Conjugate(S[y]^2) type answers in the output of my function.

• Maybe real[m : {{__Real} ..}] := m * 10
– eldo
Oct 5, 2014 at 12:24
• This is why you should put more effort in asking clear questions from the get go. Oct 5, 2014 at 13:57
• I thought it was quite clear, but obviously not! What was unclear @RunnyKine? Oct 5, 2014 at 13:58
• I just meant your clarification would have been nice from the beginning. Oct 5, 2014 at 14:02

Update: after clarification I propose

f[m_] := Block[{\$Assumptions = Alternatives @@ Flatten@m ∈ Reals},
Conjugate[m[[1, 1]]] // Simplify]

f[{{x, x^2}, {h[x], S[y]^2}}]
(* x *)


From the documentation of MatrixQ

Test if a matrix has real numeric entries:

MatrixQ[{{Pi, Sin}, {Cos, E}}, Im[#] == 0 &]


Faster test for real-valued numbers:

MatrixQ[{{1, 2.}, {3/4, 520}}, NumberQ[#] && ! MatchQ[#, _Complex] &]


So you can use

real[m_ /; MatrixQ[m, Im[#] == 0 &]] := m


or

real[m_ /; MatrixQ[m, NumberQ[#] && ! MatchQ[#, _Complex] &]] := m


For big matrices the following will be considerably faster

ClearAll[real]
real[m_ /; MatrixQ[m] && Norm[Im[m], ∞] == 0] := m

real[RandomReal[1, {3000, 3000}]] // Head // AbsoluteTiming
(* {0.332791, List} *)


Note: My method accept complex arrays with zero imaginary part.

• If you don't want to accept, use kguler's solution.
• If you want to accept and get rid of the imaginary part just use Re[m] inside the function.
• I'm not dealing with numeric matrices, and I don't want to 'test' to see if it's real. I want Mathematica to assume that any functions inside the matrix are real, so I avoid Conjugate(function) etc. Oct 5, 2014 at 13:47
rmQ = MatrixQ[#, InternalRealValuedNumericQ] &;

ClearAll[realB, real]
real[m_ /; MatrixQ[m] && Norm[Im[m], \[Infinity]] == 0] := m
realB[m_?rmQ] := m

real[RandomReal[1, {3000, 3000}]] // Head // AbsoluteTiming
(* {0.312443,List} *)
realB[RandomReal[1, {3000, 3000}]] // Head // AbsoluteTiming
(* {0.093755,List} *)


Maybe this will work for you.

 validNum = Except[_Complex, _?NumericQ];
f[m : {{validNum ..} ..}] := m


f will accept a wide variety number forms but not complex numbers.

f[{{1, 2.}, {3/4, π}, {5, 6}}]

{{1, 2.}, {3/4, π}, {5, 6}}

f[{{1 + I, 2.}, {3/4, π}, {5, 6}}]

f[{{1 + I, 2.}, {3/4, π}, {5, 6}}]


Nor will it accept forms that are not matrix-like.

{f[], f, f[{1, 2, 3}], f[{{1, 2.}, π, {5, 6}}]}

{f[], f, f[{1, 2, 3}], f[{{1, 2.}, π, {5, 6}}]}


However, it does not care if the matrix rows are not all the same length.

 f[{{1, 2.}, {π}, {5, 6}}]

 {{1, 2.}, {π}, {5, 6}}