{"id":3217,"date":"2011-02-22T15:21:57","date_gmt":"2011-02-22T14:21:57","guid":{"rendered":"http:\/\/www.walkingrandomly.com\/?p=3217"},"modified":"2011-02-28T11:05:46","modified_gmt":"2011-02-28T10:05:46","slug":"mathematica-the-difference-between-equal-and-sameq","status":"publish","type":"post","link":"https:\/\/walkingrandomly.com\/?p=3217","title":{"rendered":"Mathematica &#8211; The difference between Equal and SameQ"},"content":{"rendered":"<p>A Mathematica user contacted me recently and asked why<\/p>\n<pre>(1\/16 Cos[a] (Cos[b] + 15 Cos[3 b])) === (1\/8 Cos[b] (-7 + 15 Cos[2b])Cos[a])\r\n<\/pre>\n<p>returned False when he expected True.  Let&#8217;s take a look at what is going on here.<\/p>\n<p>The SameQ command (===) and the Equal command (==) are subtly different.\u00a0 Equal (==) tests to see if two expressions are <strong>mathematically equivalent<\/strong> whereas SameQ tests to see if they are <strong>structurally equivalent<\/strong>.\u00a0 In general, SameQ is the stricter of the two tests and is often too strict for our needs.<\/p>\n<p><strong>A very simple example<\/strong><\/p>\n<p>The simplest example might be to compare 2 and 2. (That is 2 with a period at the end)<\/p>\n<p>Mathematically these are the same since they both represent the number two.  However, from a Mathematica structural point of view, they are different since one has infinite precision whereas the other has double precision.  So, we have<\/p>\n<pre>2==2. gives True\r\n2===2. gives False<\/pre>\n<p><strong>A more complicated example<\/strong><\/p>\n<pre>Sqrt[2] + Sqrt[3] == Sqrt[5 + 2 Sqrt[6]] which gives True\r\nSqrt[2] + Sqrt[3] === Sqrt[5 + 2 Sqrt[6]] which gives False\r\n<\/pre>\n<p>Mathematically the above is always true but the structure of the expressions on the LHS and RHS are different under normal evaluation rules.<\/p>\n<p>So, what do I mean by &#8216;structurally equivalent?&#8217;.\u00a0 To be honest, I am slightly woolly on this myself but in my head I consider two expressions to be structurally equivalent if their TreeForms are the same<\/p>\n<pre>TreeForm[Sqrt[2] + Sqrt[3] ]\r\n<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/www.walkingrandomly.com\/images\/mathematica8\/treeform_lhs.png\" alt=\"TreeForm[Sqrt[2] + Sqrt[3] ]\" \/><\/p>\n<pre>TreeForm[Sqrt[5 + 2 Sqrt[6]] ]\r\n<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/www.walkingrandomly.com\/images\/mathematica8\/treeform_rhs.png\" alt=\"TreeForm[Sqrt[5 + 2 Sqrt[6]] ]]\" \/><\/p>\n<p>The important thing to remember here is that the argument to TreeForm is evaluated by Mathematica before it gets passed to TreeForm.  So, the above images show us that under normal evaluation rules, these two expressions have different structural forms.\u00a0 In the next example we&#8217;ll see how this detail can matter<\/p>\n<p><strong>Exp[I Pi] and all that<br \/>\n<\/strong><\/p>\n<p>Let&#8217;s look at<\/p>\n<pre>Exp[I Pi] === -1\r\n<\/pre>\n<p>Would that be True or False based on what we have seen so far?\u00a0  It is certainly mathematically true but remember that a triple equals requires both sides to be structurally equivalent and at first sight it appears that this isn&#8217;t the case here.  You might expect Exp[I Pi] to have a very different TreeForm from -1 and so you&#8217;d expect the above to evaluate to False.  However if you do<\/p>\n<pre>TreeForm[Exp[I Pi]]\r\n<\/pre>\n<p>then you get a single box containing -1.  This occurs because Mathematica evaluates Exp[I Pi] to -1 before passing to TreeForm.  This evaluation also occurs when you do Exp[I Pi] === -1 so what you are really testing is -1===-1 which is obviously True.<\/p>\n<p><strong>Back to the original example<br \/>\n<\/strong><\/p>\n<pre>(1\/16 Cos[a] (Cos[b] + 15 Cos[3 b])) === (1\/8 Cos[b] (-7 + 15 Cos[2b])Cos[a])\r\n<\/pre>\n<p>If you use === then it returns False and this is &#8216;obviously&#8217; the case because if you evaluate the TreeForms of both expressions then you&#8217;ll see that they get stored with different structural forms after being evaluated.<\/p>\n<pre>TreeForm[(1\/16 Cos[a] (Cos[b] + 15 Cos[3 b]))]\r\n<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/www.walkingrandomly.com\/images\/mathematica8\/treeform1_lhs.png\" alt=\"TreeForm[(1\/16 Cos[a] (Cos[b] + 15 Cos[3 b]))]\" \/><\/p>\n<pre>TreeForm[(1\/8 Cos[b] (-7 + 15 Cos[2 b]) Cos[a])]\r\n<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/www.walkingrandomly.com\/images\/mathematica8\/treeform1_rhs.png\" alt=\"TreeForm[(1\/8 Cos[b] (-7 + 15 Cos[2 b]) Cos[a])]]\" \/><\/p>\n<p>Since we are interested in mathematical equivalence, however, we use ==<\/p>\n<pre>(1\/16 Cos[a] (Cos[b] + 15 Cos[3 b])) == (1\/8 Cos[b] (-7 + 15 Cos[2 b]) Cos[a])\r\n<\/pre>\n<p>What happens this time, however, is that Mathematica returns the original expression <strong>unevaluated<\/strong>.  This is because, under the standard set of transformations that Mathematica applies when it evaluates ==, it can&#8217;t be sure one way or the other and so it gives up.<\/p>\n<p>To proceed we wrap the whole thing in FullSimplify which essentially says to Mathematica &#8216;Use everything you&#8217;ve got to try and figure this out &#8211; no matter how long it takes&#8217;\u00a0 I.e. you allow it to use more transforms.<\/p>\n<pre>FullSimplify[(1\/16 Cos[a] (Cos[b] + 15 Cos[3 b])) == (1\/8 Cos[b] (-7 + 15 Cos[2 b]) Cos[a])]\r\n\r\nTrue\r\n<\/pre>\n<p>Finally, we have the result that the user expected.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A Mathematica user contacted me recently and asked why (1\/16 Cos[a] (Cos[b] + 15 Cos[3 b])) === (1\/8 Cos[b] (-7 + 15 Cos[2b])Cos[a]) returned False when he expected True. Let&#8217;s take a look at what is going on here. The SameQ command (===) and the Equal command (==) are subtly different.\u00a0 Equal (==) tests to [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[8,7],"tags":[],"class_list":["post-3217","post","type-post","status-publish","format-standard","hentry","category-mathematica","category-programming"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3swhs-PT","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/3217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3217"}],"version-history":[{"count":23,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/3217\/revisions"}],"predecessor-version":[{"id":3238,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/3217\/revisions\/3238"}],"wp:attachment":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}