TransWikia.com

Good Practice in Defining Numeric Functions

Mathematica Asked by JP-Ellis on April 3, 2021

I would like to define numeric functions for Mathematica such that they behave ‘nicely’ in much the same way as the built-in numeric functions do. For example, consider the following numerical function from Mathematica:

HypergeometricPFQ[{1/2, 1/3}, {1/4, 1/5}, x]
HypergeometricPFQ[{1/2, 1/3}, {1/4, 1/5}, 1]
HypergeometricPFQ[{1/2, 1/3}, {1/4, 1/5}, 1.0]

The first two return a ‘nice’ output that is symbolic while the last one returns a number. Furthermore, the 2nd one above can be used numerically but only becomes a floating point if it is combined with another imprecise number (that is, if I multiply it by Pi it remains symbolic, while multiplying by 3.14 returns a number). Furthermore, NumericQ returns True for the latter two.

How do I replicate such behaviour in my own definitions of numerical functions? Take for example:

f[x_] := NIntegrate[t^(t-x), {t, 1, x}]

2 Answers

You mainly need NumericFunction attribute. You may also need Listable attribute that many numeric functions own:

ClearAll@f
SetAttributes[f, {NumericFunction, Listable}]
f[x_ /; Precision[x] != Infinity] := 
 NIntegrate[t^(t - x), {t, 1, x}, WorkingPrecision -> Precision@x]


f[{x, 2, 2.}]
(* {f[x], f[2], 0.874227} *)    

f[x] // NumericQ
(* False *)

f[2] // NumericQ
(* True *)

f[2.] // NumericQ
(* True *)

f[2] + 1.
(* 1.87423 *)

N[f[2], 16]
(* 0.8742270873919437 *)

Correct answer by xzczd on April 3, 2021

?NumericFunction

give a definition for Mathematica for NumericFunction. There is the documentation page for NumericFunction. And there is the great input:

list=Select[Names["System`*"], MemberQ[Attributes[#], NumericFunction] &];

MemberQ[list, HypergeometricPFQ_]

(True)

The definition is:

"NumericFunction is an attribute that can be assigned to a symbol f to indicate that f[Subscript[arg, 1],Subscript[arg, 2],[Ellipsis]] should be considered a numeric quantity whenever all the Subscript[arg, i] are numeric quantities. "

The input for defining a function in Mathematica is

SetAttributes[f, NumericFunction]

This generates no output explicit.

The condition for a confirmation is easily matched, all arguments have to be numeric and the the output of the function has to be numeric. With the explicit definition above that is already matched if the arguments are numeric.

f[2 + 3 I] // Numeric

(* True *)

This is rather short compared for example for the effort to define a Function. Important is that NumeriQ is independent of the body in Wolfram Language definition. It depends on the input arguments and the output. NumericQ is only valid so far for scalars.

F[x_, y_] := {x + y, x - y}
F[5, 6] // NumericQ

(* False *)

On the documentation page for NumberQ there is a table in the section Properties and Relations that offers some ideas for tests with NumericQ and defines the check to do for the arguments.

TableForm[
 Table[{x, NumberQ[x], 
   MatchQ[#, _Integer | _Rational | _Real | _Complex] &[x], 
   NumericQ[x]}, {x, {1, 3/2, 1.5, 1 + I, E, Sin[1], 
    HypergeometricPFQ[{1/2, 1/3}, {1/4, 1/5}, y], 
    HypergeometricPFQ[{1/2, 1/3}, {1/4, 1/5}, 1], 
    HypergeometricPFQ[{1/2, 1/3}, {1/4, 1/5}, 1.0], Underflow[], 
    Overflow[], Abs[-1 + I], RealAbs[-1], Arg[-1 - I], f[1], f[I], 
    f[Sin[0]], F[2, 3], F[I, -I], Infinity}}], 
 TableHeadings -> {{}, {"x", "NumberQ", "MatchQ", "NumericQ"}}]

table with the output

So there is a vast collection of functions that is in need to be known how it is implemented in Mathematica and Wolfram Language

There is an easy rule:

If NumberQ[x] is True, then NumericQ[x] is also True.

Mathematica/Wolfram Language has the InexactNumberQ that will extend the table with more columns and rows.

An impressive perspective on how does a function in Mathematica/Wolfram Language not behave 'nicely'?

InexactNumberQ, Not[MachineNumberQ], ListQ, StringQ, MatrixQ, ArrayQ, VectorQ, AssociationQ and others. Mathematica/WL knows Dimensions, Colors, Graphs, Intervals and more.

Names["*Q"]

A different perspective is

Names["*Function"]

to create functions that do not well behave for NumericQ.

For most really needed that compilation Compile does not alter the attribute NumericFunction.

For investigation the built-in Attributes. This how-to-restore-function-attributes-to-default shows how to deal with the combination of function attributes. This is extended in the built-in Protected documentation page.

Answered by Steffen Jaeschke on April 3, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP