# Modifying codes in a more 'Mathematica' way

I have the following codes:

result={};
x=1.0; (* x is an independent variable *)
ans=NSolve[Det[Mat[x,y]]==0, y];
y1=y/.ans[[1]];
y2=y/.ans[[2]]; (*not necessarily two solutions *)
yfinal=Abs[y2-y1];
AppendTo[Result,{x,yfinal}]


I have a matrix Mat which depends on both x and y. I want to find values of y that satisfy Det[Mat[x,y]]==0, treating x as the independent variable and y the dependent variable. I will get more than one solution (not necessarily two), and I am interested in the absolute difference between the largest and smallest y. I want to repeat this for a range of values of x so I can obtain a table showing the pairs {x,y} which will be used for results analysis like plotting graph.

What is the most elegant and 'Mathematica' way to automate this (I provide the range and stepsize for x, and it can automatically find all the corresponding yfinal)? I used to program in python and Matlab (though not very good at them as well), and I am pretty new to Mathematica, so I am still trying to adapt to its way of programming. Any help would be appreciated.

• Could you specify Mat (which should better be lowercase as Alan has pointed out) and maybe also give some rangespecs for x (e.g. {from, to, stepsize})? – gwr Aug 18 '16 at 14:33
• Note that "most elegant and Mathematica way" is a pleonasm. :) – gwr Aug 18 '16 at 14:36

You did not provide Mat (btw, don't capitalize your own symbols), but the following illustrates one approach to what you describe (edited):

xs = Range[10]
solns = Solve[y^2 == #, y] & /@ xs
yss = SortBy[y /. #, N] & /@ solns
results = (Last[#] - First[#]) & /@ yss


If you know your solutions will all be numerical, you can just use Sort. (Btw, you seemed to assume the results are real, so I did too.)

• thanks, but how can I automate the whole process, like making a function to enclose everything, so that when I enter the range and stepsize for x, it can generate all the points in the list result? – Physicist Aug 18 '16 at 14:23
• @Physicist Answer changed in response to comment. – Alan Aug 18 '16 at 14:30

Another way:

(* ad hoc def. of Mat[] *)
ClearAll[Mat];
Mat[x_, y_] := {
{2 y, x, 1},
{x + y, 0, -x},
{x, 2, y}
};

Block[{x = 1.0},
First@ Differences@ MinMax[y /. NSolve[Det[Mat[x, y]] == 0, y, Reals]]
]
(*  6.08276  *)


Or, if you want a function:

ClearAll[range];
range::toofew = "not enough real solutions";
range[x_?NumericQ] :=
Module[{sols = y /. NSolve[Det[Mat[x, y]] == 0, y, Reals]},
If[Length@sols < 2, Message[range::toofew]];
First@ Differences@ MinMax[sols] /; Length@sols >= 2]


Usage:

range[1.0]
(*  6.08276  *)

range[-0.5]