Related
To illustrate my problem here is a toy example:
F[x_] := Module[{out},
If[x > 1,
out = 1/2,
out = 1
];
out
];
The function can be evaluated and plotted. However when I try to numerically integrate it I get an error
NIntegrate[F[x], {x, 0, 2}]
NIntegrate::inumr: The integrand out$831 has evaluated to non-numerical values for all sampling points in the region with boundaries {{0,2}}. >>
Integrate and some other functions will do some probing with symbolic values first. Your Module when given only the symbol x will return only the (aliased) out.
Fix this by defining your F only for numeric values. NIntegrate will discover this and then use numeric values.
In[1]:= F[x_?NumericQ] := Module[{out},
If[x > 1, out = 1/2, out = 1]; out];
NIntegrate[F[x], {x, 0, 2}]
Out[2]= 1.5
I have a list and I want to apply a logical test to each element, and if any one of them does not satisfy this condition, then return false. I want to write this in Mathematica or find a built-in function, but seems ForAll does not actually do that.
My question is: how to do this most efficiently?
Bonus: how about similarly for Exists function: i.e. if there is any element in the list satisfy the condition, return true.
The answer to the first portion of your question might be something along these lines:
forAll[list_, cond_] := Select[list, ! cond## &, 1] === {};
which is used like this:
forAll[{1, 2, 3, 3.5}, IntegerQ]
The "exists" function is already natively implemented as MemberQ. It could be reimplemented as:
exists[list_,cond_] := Select[list, cond, 1] =!= {};
Use it like
exists[Range#100, (10 == # &)]
which returns true as 10 is an element causing the Select to return {10} which is not equal to {}.
This answer is not intended to show the most efficient method, but rather an alternative method that serves the pedagogical purpose of showing some important core functionality in Mathematica.
nixeagle's answer avoids explicitly testing every element of the list. If the test doesn't lend itself to inclusion in the third argument of Select, then the below might be useful.
To do this, you need to learn about the standard Or and And functions, as well as the Map (/#) and Apply (##) commands which are extremely important for any Mathematica user to learn. (see this tutorial)
Here is a simple example.
In[2]:= data = RandomInteger[{0, 10}, {10}]
Out[2]= {10, 1, 0, 10, 1, 5, 2, 2, 4, 1}
In[4]:= # > 5 & /# data
Out[4]= {True, False, False, True, False, False, False, False, False, \
False}
In[6]:= And ## (# > 5 & /# data)
Out[6]= False
What is going on here is that you are mapping the function ("greater than 5") to each element of the list using Map, to get a list of True/False values. You are then applying the standard logical function And to the whole list to get the single Boolean value.
These are all very much core functionality in Mathematica and I recommend you read the documentation for these functions carefully and practice using them.
This is not the most efficient method, but for small problems you will not notice the difference.
In[11]:= Do[Select[data, ! # > 5 &, 1] === {}, {10000}] // Timing
Out[11]= {0.031, Null}
In[12]:= Do[And ## (# > 5 & /# data);, {10000}] // Timing
Out[12]= {0.11, Null}
For Exists, the alternative to Select would be MatchQ for patterns or MemberQ for explicit values. The documentation has some useful examples.
Not to be taken too seriously, but this
ClearAll[existsC];
existsC[cond_] := With[
{c = cond},
Compile[
{{l, _Integer, 1}},
Module[
{flag = False, len = Length#l},
Do[
If[cond[l[[i]]],
flag = True; Break[];
];,
{i, 1, len}];
flag
],
CompilationTarget -> "C"
]
]
appears to be around 300 times faster than nixeagle's solutions on my machine. What this does is to emit a compiled function which takes a list and compares its elements to the given condition (fixed at compile-time), returning True if any of them matches.
It is used as follows: Compile with the appropriate cond, eg
t = existsC[# == 99999 &];
and then
t[Range#100000] // timeIt
returns 2.33376*10^-6 (a worst-case scenario, as I am just searching linearly and the matching element is at the end) while
exists[Range#100000, (99999 == # &)] // timeIt
returns 0.000237162 (here, timeIt is this).
A pattern based approach:
forAll[list_, test_] := MatchQ[ list, _[__?test] ]
MemberQ already implements exists.
Mathematica 10 has a new function for this: AllTrue. When all elements pass the test my function appears to be a bit faster:
a = Range[2, 1*^7, 2];
AllTrue[a, EvenQ] // Timing // First
forAll[a, EvenQ] // Timing // First
1.014007
0.936006
However with an early exit the benefit of the new function becomes apparent:
a[[123456]] = 1;
AllTrue[a, EvenQ] // Timing // First
forAll[a, EvenQ] // Timing // First
0.031200
0.265202
Even though && and || perform short-circuit evaluation, i.e., don't evaluate their arguments unnecessarily, I suspect that solutions based on Select[] or Map[] won't benefit much from this. That's because they apply the logical test to every element, building a list of Boolean truth-values before performing the conjunction/disjunction among them. If the test you've specified is slow, it can be a real bottleneck.
So here is a variant that does short-circuit evaluation of the condition as well:
allSatisfy[list_, cond_] :=
Catch[Fold[If[cond[#2], True, Throw[False]] &, True, list]]
Testing if any element in the list satisfies the condition is nicely symmetric:
anySatisfy[list_, cond_] :=
Catch[Fold[If[cond[#2], Throw[True], False] &, False, list]]
Of course this could equally have been done (and candidly speaking, more easily) using procedural loops such as While[], but I have a soft spot for functional programming!
nixeagle got the bonus part, but the way I would've done the first part is as follows:
AllSatisfy[expr_, cond_] := Length#Select[expr, cond] == Length#expr
There's a simple solution:
In[1401]:= a = {1, 2, 3}
Out[1401]= {1, 2, 3}
In[1398]:= Boole[Thread[a[[2]] == a]]
Out[1398]= {0, 1, 0}
In[1400]:= Boole[Thread[a[[2]] >= a]]
Out[1400]= {1, 1, 0}
In[1402]:= Boole[Thread[a[[2]] != a]]
Out[1402]= {1, 0, 1}
Success!
If I do the following in Mathematica
f[l_] := Module[{}, l[[1]] = Append[l[[1]], 3]; l]
f[{{}, 3}]
I get an error:
Set::setps: "{{},3} in the part assignment is not a symbol. "
Even l={{}, 3};f[l] gets the same error. But I can do f[l_] := Module[{}, {Append[l[[1]], 3],l[[2]]}] or l = {{}, 3}; l[[1]] = Append[l[[1]], 3]; l.
What is your explanation?
There are multiple problems here:
Attempting Part assignment on a non-Symbol, just as the error message states.
Attempting to manipulate a named replacement object as though it were a symbol.
The replacement that takes place in this construct:
f[x_] := head[x, 2, 3]
Is analogous to that of With:
With[{x = something}, head[x, 2, 3]]
That is, the substitution is made directly and before evaluation, such that the function Head never even sees an object x. Look what happens with this:
ClearAll[f,x]
x = 5;
f[x_] := (x = x+2; x)
f[x]
During evaluation of In[8]:= Set::setraw: Cannot assign to raw object 5. >>
Out[]= 5
This evaluates as: (5 = 5+2; 5) so not only is assignment to 5 impossible, but all instances of x that appear in the right hand side of := are replaced with the value of x when it is fed to f. Consider what happens if we try to bypass the assignment problem by using a function with side effects:
ClearAll[f, x, incrementX]
incrementX[] := (x += 2)
x = 3;
incrementX[];
x
5
So our incrementX function is working. But now we try:
f[x_] := (incrementX[]; x)
f[x]
5
incrementX did not fail:
x
7
Rather, the the value of x was 5 at the time of evaluation of f[x] and therefore that is returned.
What does work?
What options do we have for things related to what you are attempting? There are several.
1. Use a Hold attribute
We can set a Hold attribute such as HoldFirst or HoldAll on the function, so that we may pass the symbol name to RHS functions, rather than only its value.
ClearAll[heldF]
SetAttributes[heldF, HoldAll]
x = {1, 2, 3};
heldF[x_] := (x[[1]] = 7; x)
heldF[x]
x
<pre>{7, 2, 3}</pre>
<pre>{7, 2, 3}</pre>
We see that both the global value of x, and the x expression returned by heldF are changed. Note that heldF must be given a Symbol as an argument otherwise you are again attempting {1, 2, 3}[[1]] = 7.
2. Use a temporary Symbol
As Arnoud Buzing shows, we can also use a temporary Symbol in Module.
ClearAll[proxyF]
x = {1, 2, 3};
proxyF[x_] := Module[{proxy = x}, proxy[[1]] = 7; proxy]
proxyF[x]
proxyF[{1, 2, 3}]
x
{7, 2, 3}
{7, 2, 3}
{1, 2, 3}
3. Use ReplacePart
We can also avoid symbols completely and just use ReplacePart:
ClearAll[directF]
x = {1, 2, 3};
directF[x_] := ReplacePart[x, 1 -> 7]
directF[x]
x
{7, 2, 3}
{1, 2, 3}
This can be used for modifications rather than outright replacements as well:
ClearAll[f]
f[l_] := ReplacePart[l, 1 :> l[[1]] ~Append~ 3]
f[{{}, 3}]
{{3}, 3}
Try
f[{{}, 3}] // Trace
and you see that the value of l is inserted into the l[[1]] = Append[l[[1]], 3] bit before evaluation. So mma is attempting to evaluate this: {{}, 3}[[1]] = {3}
This may do something like you want
ClearAll[f];
f[l_] := Module[{},
Append[l[[1]], 3]~Join~Rest[l]
]
(the idea is to avoid assigning to parts of l, since l will be evaluated before the assignment is attempted)
If you do want to use Part in your Module, you may want to consider using a temporary variable:
f[l_List] := Module[{t = l}, t[[1]] = Pi; t]
And:
In[] := f[{1, 2, 3}]
Out[] = {Pi, 2, 3}
On the documentation page for Equal we read that
Approximate numbers with machine
precision or higher are considered
equal if they differ in at most their
last seven binary digits (roughly
their last two decimal digits).
Here are examples (32 bit system; for 64 bit system add some more zeros in the middle):
In[1]:= 1.0000000000000021 == 1.0000000000000022
1.0000000000000021 === 1.0000000000000022
Out[1]= True
Out[2]= True
I'm wondering is there a "normal" analog of the Equal function in Mathematica that does not drop last 7 binary digits?
Thanks to recent post on the official newsgroup by Oleksandr Rasputinov, now I have learned two undocumented functions which control the tolerance of Equal and SameQ: $EqualTolerance and $SameQTolerance. In Mathematica version 5 and earlier these functions live in the Experimental` context and are well documented: $EqualTolerance, $SameQTolerance. Starting from version 6, they are moved to the Internal` context and become undocumented but still work and even have built-in diagnostic messages which appear when one try to assign them illegal values:
In[1]:= Internal`$SameQTolerance = a
During evaluation of In[2]:= Internal`$SameQTolerance::tolset:
Cannot set Internal`$SameQTolerance to a; value must be a real
number or +/- Infinity.
Out[1]= a
Citing Oleksandr Rasputinov:
Internal`$EqualTolerance ... takes a
machine real value indicating the
number of decimal digits' tolerance
that should be applied, i.e.
Log[2]/Log[10] times the number of
least significant bits one wishes to
ignore.
In this way, setting Internal`$EqualTolerance to zero will force Equal to consider numbers equal only when they are identical in all binary digits (not considering out-of-Precision digits):
In[2]:= Block[{Internal`$EqualTolerance = 0},
1.0000000000000021 == 1.0000000000000022]
Out[2]= False
In[5]:= Block[{Internal`$EqualTolerance = 0},
1.00000000000000002 == 1.000000000000000029]
Block[{Internal`$EqualTolerance = 0},
1.000000000000000020 == 1.000000000000000029]
Out[5]= True
Out[6]= False
Note the following case:
In[3]:= Block[{Internal`$EqualTolerance = 0},
1.0000000000000020 == 1.0000000000000021]
RealDigits[1.0000000000000020, 2] === RealDigits[1.0000000000000021, 2]
Out[3]= True
Out[4]= True
In this case both numbers have MachinePrecision which effectively is
In[5]:= $MachinePrecision
Out[5]= 15.9546
(53*Log[10, 2]). With such precision these numbers are identical in all binary digits:
In[6]:= RealDigits[1.0000000000000020` $MachinePrecision, 2] ===
RealDigits[1.0000000000000021` $MachinePrecision, 2]
Out[6]= True
Increasing precision to 16 makes them different arbitrary-precision numbers:
In[7]:= RealDigits[1.0000000000000020`16, 2] ===
RealDigits[1.0000000000000021`16, 2]
Out[7]= False
In[8]:= Row#First#RealDigits[1.0000000000000020`16,2]
Row#First#RealDigits[1.0000000000000021`16,2]
Out[9]= 100000000000000000000000000000000000000000000000010010
Out[10]= 100000000000000000000000000000000000000000000000010011
But unfortunately Equal still fails to distinguish them:
In[11]:= Block[{Internal`$EqualTolerance = 0},
{1.00000000000000002`16 == 1.000000000000000021`16,
1.00000000000000002`17 == 1.000000000000000021`17,
1.00000000000000002`18 == 1.000000000000000021`18}]
Out[11]= {True, True, False}
There is an infinite number of such cases:
In[12]:= Block[{Internal`$EqualTolerance = 0},
Cases[Table[a = SetPrecision[1., n];
b = a + 10^-n; {n, a == b, RealDigits[a, 2] === RealDigits[b, 2],
Order[a, b] == 0}, {n, 15, 300}], {_, True, False, _}]] // Length
Out[12]= 192
Interestingly, sometimes RealDigits returns identical digits while Order shows that internal representations of expressions are not identical:
In[13]:= Block[{Internal`$EqualTolerance = 0},
Cases[Table[a = SetPrecision[1., n];
b = a + 10^-n; {n, a == b, RealDigits[a, 2] === RealDigits[b, 2],
Order[a, b] == 0}, {n, 15, 300}], {_, _, True, False}]] // Length
Out[13]= 64
But it seems that opposite situation newer happens:
In[14]:=
Block[{Internal`$EqualTolerance = 0},
Cases[Table[a = SetPrecision[1., n];
b = a + 10^-n; {n, a == b, RealDigits[a, 2] === RealDigits[b, 2],
Order[a, b] == 0}, {n, 15, 3000}], {_, _, False, True}]] // Length
Out[14]= 0
Try this:
realEqual[a_, b_] := SameQ ## RealDigits[{a, b}, 2, Automatic]
The choice of base 2 is crucial to ensure that you are comparing the internal representations.
In[54]:= realEqual[1.0000000000000021, 1.0000000000000021]
Out[54]= True
In[55]:= realEqual[1.0000000000000021, 1.0000000000000022]
Out[55]= False
In[56]:= realEqual[
1.000000000000000000000000000000000000000000000000000000000000000022
, 1.000000000000000000000000000000000000000000000000000000000000000023
]
Out[56]= False
In[12]:= MyEqual[x_, y_] := Order[x, y] == 0
In[13]:= MyEqual[1.0000000000000021, 1.0000000000000022]
Out[13]= False
In[14]:= MyEqual[1.0000000000000021, 1.0000000000000021]
Out[14]= True
This tests if two object are identical, since 1.0000000000000021 and 1.000000000000002100 differs in precision they won't be considered as identical.
I'm not aware of an already defined operator. But you may define for example:
longEqual[x_, y_] := Block[{$MaxPrecision = 20, $MinPrecision = 20},
Equal[x - y, 0.]]
Such as:
longEqual[1.00000000000000223, 1.00000000000000223]
True
longEqual[1.00000000000000223, 1.00000000000000222]
False
Edit
If you want to generalize for an arbitrary number of digits, you can do for example:
longEqual[x_, y_] :=
Block[{
$MaxPrecision = Max ## StringLength /# ToString /# {x, y},
$MinPrecision = Max ## StringLength /# ToString /# {x, y}},
Equal[x - y, 0.]]
So that your counterexample in your comment also works.
HTH!
I propose a strategy that uses RealDigits to compare the actual digits of the numbers. The only tricky bit is stripping out trailing zeroes.
trunc = {Drop[First##, Plus ## First /# {-Dimensions#First##,
Last#Position[First##, n_?(# != 0 &)]}], Last##} &# RealDigits## &;
exactEqual = SameQ ## trunc /# {#1, #2} &;
In[1] := exactEqual[1.000000000000000000000000000000000000000000000000000111,
1.000000000000000000000000000000000000000000000000000111000]
Out[1] := True
In[2] := exactEqual[1.000000000000000000000000000000000000000000000000000111,
1.000000000000000000000000000000000000000000000000000112000]
Out[2] := False
I think that you really have to specify what you want... there's no way to compare approximate real numbers that will satisfy everyone in every situation.
Anyway, here's a couple more options:
In[1]:= realEqual[lhs_,rhs_,tol_:$MachineEpsilon] := 0==Chop[lhs-rhs,tol]
In[2]:= Equal[1.0000000000000021,1.0000000000000021]
realEqual[1.0000000000000021,1.0000000000000021]
Out[2]= True
Out[3]= True
In[4]:= Equal[1.0000000000000022,1.0000000000000021]
realEqual[1.0000000000000022,1.0000000000000021]
Out[4]= True
Out[5]= False
As the precision of both numbers gets higher, then they can always be distinguished if you set tol high enough.
Note that the subtraction is done at the precision of the lowest of the two numbers. You could make it happen at the precision of the higher number (which seems a bit pointless) by doing something like
maxEqual[lhs_, rhs_] := With[{prec = Max[Precision /# {lhs, rhs}]},
0 === Chop[SetPrecision[lhs, prec] - SetPrecision[rhs, prec], 10^-prec]]
maybe using the minimum precision makes more sense
minEqual[lhs_, rhs_] := With[{prec = Min[Precision /# {lhs, rhs}]},
0 === Chop[SetPrecision[lhs, prec] - SetPrecision[rhs, prec], 10^-prec]]
One other way to define such function is by using SetPrecision:
MyEqual[a_, b_] := SetPrecision[a, Precision[a] + 3] == SetPrecision[b, Precision[b] + 3]
This seems to work in the all cases but I'm still wondering is there a built-in function. It is ugly to use high-level functions for such a primitive task...
I'd like a function AnyTrue[expr,{i,{i1,i2,...}}] which checks if expr is True for any of i1,i2... It should be as if AnyTrue was Table followed by Or##%, with the difference that it only evaluates expr until first True is found.
Short-circuiting part is optional, what I'd really like to know is the proper way to emulate Table's non-standard evaluation sequence.
Update 11/14
Here's a solution due to Michael, you can use it to chain "for all" and "there exists" checks
SetAttributes[AllTrue, HoldAll];
SetAttributes[AnyTrue, HoldAll];
AllTrue[{var_Symbol, lis_List}, expr_] :=
LengthWhile[lis,
TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]] &] ==
Length[lis];
AnyTrue[{var_Symbol, lis_List}, expr_] :=
LengthWhile[lis,
Not[TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]]] &] <
Length[lis];
AllTrue[{a, {1, 3, 5}}, AnyTrue[{b, {2, 4, 5}}, EvenQ[a + b]]]
AnyTrue[{a, {1, 3, 5}}, AllTrue[{b, {2, 4, 5}}, EvenQ[a + b]]]
How about this?
SetAttributes[AnyTrue, HoldAll];
AnyTrue[expr_, {var_Symbol, lis_List}] :=
LengthWhile[lis,
Not[TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]]] &
] < Length[lis]
Includes short-circuiting via LengthWhile and keeps everything held where necessary so that things work as expected with var has a value outside the function:
In[161]:= x = 777;
In[162]:= AnyTrue[Print["x=", x]; x == 3, {x, {1, 2, 3, 4, 5}}]
During evaluation of In[162]:= x=1
During evaluation of In[162]:= x=2
During evaluation of In[162]:= x=3
Out[162]= True
The built-in Or is short-circuiting, too, for what it's worth. (but I realize building up the unevaluated terms with e.g. Table is a pain):
In[173]:= Or[Print[1];True, Print[2];False]
During evaluation of In[173]:= 1
Out[173]= True
This doesn't match your spec but I often use the following utility functions, which are similar to what you have in mind (they use pure functions instead of expressions with a specified variable) and also do short-circuiting:
some[f_, l_List] := True === (* Whether f applied to some *)
Scan[If[f[#], Return[True]]&, l]; (* element of list is True. *)
every[f_, l_List] := Null === (* Similarly, And ## f/#l *)
Scan[If[!f[#], Return[False]]&, l]; (* (but with lazy evaluation). *)
For example, Michael Pilat's example would become this:
In[1]:= some[(Print["x=", #]; # == 3)&, {1, 2, 3, 4, 5}]
During evaluation of In[1]:= x=1
During evaluation of In[1]:= x=2
During evaluation of In[1]:= x=3
Out[1]= True