(* Checking validity of the input function *) BeginPackage["checkfun`"] checkfun::usage = "checkfun[inp, fname] checks whether the string inp\n represents a legitimate analytic function named fname of x.\n To use different arguments, define the global variable checkfunarguments as a list of arguments. Returns expression if the function is valid or False if not." checkmin::usage = "checkmin[fun, fname, xguess] checks whether the function fname(x) = fun\n has a minimum.\n xguess is an expected position of the minimum.\n Returns x_min if there is a minimum or False if not." Begin["`private`"] nrmrform[t_]:= ( treal = N[t]; tinteger = Round[t]; epsform = 10.^-12; If[Abs[t-tinteger]"]; If[Complement[Characters[inp], {" "}]==={}, Print["Empty input string!"]; Goto[checkfailed]; ]; (* Allowed characters *) goodsymb = Characters[" ^*()_+-[],./"]; goodchar = Union[CharacterRange["a", "z"], CharacterRange["A", "Z"], CharacterRange["0", "9"], goodsymb]; inpchar = Union[Characters[inp]]; badchar = Complement[inpchar, goodchar]; If[badchar =!= {}, mbad = Length[badchar]; badrep = Table[ badchar[[nbad]] -> "" <> badchar[[nbad]] <> "" , {nbad, mbad}]; badinp = StringReplace[inp, badrep]; Print["Input expression \"", badinp,"\""]; Print[" contains one or several illegitimate ", "characters from the following list:"]; badlist = StringDrop[StringJoin[Table[ "" <> badchar[[nbad]] <> ", " , {nbad, mbad}]], -2]; Print[" ",badlist,"."]; Print[ " Please use only the following allowed ", "characters:"]; mgood = Length[goodchar]; goodlist = StringDrop[StringJoin[Table[ "" <> goodchar[[ngood]] <> ", " , {ngood, mgood}]], -2]; Print[" ",goodlist,"."]; Print[" Also notice that any single quotes (') will be ignored."]; Goto[checkfailed]; ]; (* Syntax *) exp = Check[ToExpression[inp, InputForm, Hold], ( Print["Syntax error in the expression ",inp]; Goto[checkfailed] ) ]; (* Variables *) atoms = Level[exp, {-1}]; matoms = Length[atoms]; goodvar = If[Head[Global`checkfunarguments]===List, Global`checkfunarguments, {Global`x}]; badvar = {}; Do[ atom = atoms[[natom]]; If[! NumericQ[atom] && ! MemberQ[goodvar,atom], badvar = Union[badvar, {atom}]; ]; , {natom, matoms}]; If[badvar =!= {}, badvar = ToString /@ badvar; mbad = Length[badvar]; badrep = Table[ badvar[[nbad]] -> "" <> badvar[[nbad]] <> "" , {nbad, mbad}]; badinp = StringReplace[inp, badrep]; Print["Input expression \"", badinp,"\""]; Print[" contains one or several illegitimate ", "variables from the following list:"]; badlist = StringDrop[StringJoin[Table[ "" <> badvar[[nbad]] <> ", " , {nbad, mbad}]], -2]; Print[" ",badlist,"."]; mgood = Length[goodvar]; goodlist = If[mgood==1, "an argument "<>ToString[goodvar[[1]]]<>"", "arguments "<>StringDrop[StringJoin[Table[ "" <> ToString[goodvar[[ngood]]] <> ", " , {ngood, mgood}]], -2] ]; Print[" Please use only numbers like -2, ", "3.14, Pi, E, or ",goodlist," as variables!"]; Goto[checkfailed]; ]; (* Functions *) funvar = Level[exp, {-1}, Heads -> True]; lisvar = Level[Apply[List, exp, -1], {-1}, Heads -> True]; {m, m1} = Length /@ {funvar, lisvar}; If[m != m1, Print["Unexpected error in Mathematica program during checking of syntax of the entered expression: Length[funvar]!=Length[lisvar]."]; Goto[checkfailed]; ]; heads = {}; Do[ head = funvar[[n]]; If[lisvar[[n]] === List, heads = Union[heads, {head}]; ]; , {n, m}]; inpfun = ToString /@ heads; goodfun = Union[ReadList[ToFileName[{Global`dirfunction},"allowed.txt"], Word]]; badfun = Complement[inpfun, goodfun]; If[badfun =!= {}, mbad = Length[badfun]; badrep = Table[badfun[[nbad]] <> "[" -> "" <> badfun[[nbad]] <> "[", {nbad, mbad}]; badinp = StringReplace[inp, badrep]; inpfull = StringDrop[StringReplace[ToString[FullForm[exp]], "Hold[" -> ""], -1]; badinpfull = StringReplace[inpfull, badrep]; Print["Input expression \"", badinp,"\","]; Print["or in full Mathematica form:"]; Print[" \"", badinpfull, "\""]; Print[" contains one or several illegitimate ", "functions from the following list:"]; badlist = StringDrop[ StringJoin[ Table["" <> badfun[[nbad]] <> ", ", {nbad, mbad}]], -2]; Print[" ",badlist,"."]; Print[" Please use only the following allowed ", "functions:"]; mgood = Length[goodfun]; goodlist = StringDrop[ StringJoin[ Table["" <> goodfun[[ngood]] <> ", ", {ngood, mgood}]], -2]; Print[" ",goodlist,"."]; Print[ " See description of allowed functions."]; Print[ " See list of all allowed and disallowed ", "functions."]; Goto[checkfailed]; ]; fun = Release[exp]; Print[""]; Return[TimeConstrained[Simplify[fun], 0.1, fun]]; Label[checkfailed]; Print["

Computations aborted because ", "input of the function ",fname,"(x) has some errors!

"]; Return[False]; ) checkmin[fun_, fname_String, x_, xguess_]:=( ndig = 128; Print[""]; xmin = x /. Last[fndmin]; If[!NumericQ[xmin], Print["

For some reason, there was an error in process of finding the minimum of the function ", fname," (see source text of this page)!"]; Goto[minfailed]; ]; If[Precision[xmin]===Infinity, xmin=SetAccuracy[xmin,ndig]]; nmax = 4; fexp = Series[fun, {x, xmin, nmax}]; Do[c[n] = SeriesCoefficient[fexp, n], {n, 0, nmax}]; eps = 10.^-16; If[Abs[c[1]] > eps, Print["

For some reason, the program did not succeed to find a minimum of the function ", fname,"!"]; Goto[minfailed]; ]; If[c[2] < 0, Print["

For some reason, the program found a maximum of the function ", fname,"", " instead of its minimum!"]; Goto[minfailed]; ]; If[c[2] < eps, Print["

Minimum of the function ", fname,"", " is extremely shallow!"]; Goto[minfailed]; ]; Print["

The function ",fname,"(x) has minimum at"]; Print["xmin = ",nrmrform[xmin]//prntform,"."]; Print["

Taylor expansion of the function ",fname,"(x) around the point xmin reads"]; par = "(x - xmin)"; {c0,c2,c3,c4} = nrmrform/@{c[0],c[2],c[3],c[4]}; term1 = If[c0==0,"",prntform[c0]<>" + "]; term2 = If[c2==1,par<>"2 ",prntform[c2]<>" "<>par<>"2 "]; If[ c3==0, term3 = If[c4==0,"",If[c4==1,par<>"4 ", If[c4<0,"","+ "]<>prntform[c4] <> " " <> par <> "4 " ]]; term4 = "+ O" <> par <> "5", term3 = If[c3==0,"",If[c3==1,par<>"3 ", If[c3<0,"","+ "]<>prntform[c3] <> " " <> par <> "3 " ]]; term4 = "+ O" <> par <> "4" ]; Print["
   ",fname,"(x) ~ " <> term1 <> term2 <> term3 <> term4 <> ".

"]; Return[xmin]; Label[minfailed]; Print["

Computations aborted because ", "it seems that the function ",fname,"(x) has no minimum!"]; Return[False]; ) End[] EndPackage[]