<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel rdf:about="https://community.wolfram.com">
    <title>Community RSS Feed</title>
    <link>https://community.wolfram.com</link>
    <description>RSS Feed for Wolfram Community showing any discussions tagged with Computer Science sorted by most likes.</description>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1931315" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/148287" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1017668" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/3495066" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1421180" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1330785" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/218587" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1121273" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1250668" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/935450" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/550504" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/2030201" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/3241848" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1419096" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1066381" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/2416125" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1109273" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1378496" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1112012" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/802316" />
      </rdf:Seq>
    </items>
  </channel>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1931315">
    <title>CodeParser and CodeInspector</title>
    <link>https://community.wolfram.com/groups/-/m/t/1931315</link>
    <description>[![enter image description here][2]][1]&#xD;
&#xD;
&amp;amp;[Wolfram Notebook][3]&#xD;
&#xD;
  [1]: https://youtu.be/rOa5IntICFA&#xD;
  [2]: https://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2020-04-09at12.54.33PM.png&amp;amp;userId=11733&#xD;
  [3]: https://www.wolframcloud.com/obj/afe2a2fb-ee55-4df5-a6fb-9bc16dd08af7</description>
    <dc:creator>Brenton Bostick</dc:creator>
    <dc:date>2020-04-09T15:04:38Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/148287">
    <title>Folds in a sheet of paper / metal / cloth</title>
    <link>https://community.wolfram.com/groups/-/m/t/148287</link>
    <description>I am an artist, drawing and working with 3d. Since long time, I am missing a method to form realistic folds and wrinkles into virtual sheets of paper, metal or cloth. I found some attempts within 3d-programs, but I never saw something that was not very limited or looked like rubber. Because it is so easy at reality, but so difficult at the computer, I think there is just little mathematical base.First of all: Could anybody tell me, what field of mathematics this is?&#xD;
&#xD;
&#xD;
[img=width: 800px; height: 1132px; ]/c/portal/getImageAttachment?filename=Folds-01.jpg&amp;amp;userId=145842[/img]&#xD;
&#xD;
[img=width: 800px; height: 1132px; ]/c/portal/getImageAttachment?filename=Folds-02.jpg&amp;amp;userId=145842[/img]</description>
    <dc:creator>Dietmar Klein</dc:creator>
    <dc:date>2013-11-03T23:03:23Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1017668">
    <title>Scoping constructs in Wolfram Language</title>
    <link>https://community.wolfram.com/groups/-/m/t/1017668</link>
    <description>*NOTE:  Please see the original version of this post and related discussion [**HERE**][1]. Cross-posted here per suggestion of  [Vitaliy Kaurov][2].*&#xD;
&#xD;
&#xD;
----------&#xD;
&#xD;
&#xD;
You will find a lot of information in [this][3] answer. I will add a few personal notes.&#xD;
&#xD;
##Module&#xD;
&#xD;
Use `Module` when you want to localize variables inside your function&amp;#039;s body, and those variables will potentially acquire and/or change their values during the computation.&#xD;
&#xD;
###Basic use&#xD;
&#xD;
 For example:&#xD;
&#xD;
    f[x_]:=Module[{y=x^2},y=y+x;{x,y}]&#xD;
&#xD;
Here, a local mutable variable (symbol) `y` is local to the `Module`, and is, indeed, a symbol with a unique name. This is the closest you have in Mathematica to, say, local variables in C.&#xD;
&#xD;
###Advanced uses&#xD;
&#xD;
`Module` also has advanced uses. One of them is to create closures - functions with a persistent state. My third post in [this][4] thread illustrates many cases of that and has further references. One example I will steal from there:  the following function will produce the next Fibonacci number on demand, and yet it will be as fast as the iterative loop implementation for generation of consecutive Fibonacci numbers (since Module is invoked only once, when the function is defined):&#xD;
 &#xD;
    Module[{prev, prevprev, this}, &#xD;
       reset[] := (prev = 1; prevprev = 1); &#xD;
       reset[]; &#xD;
       nextFib[] := (this = prev + prevprev; prevprev = prev; prev = this)&#xD;
    ];&#xD;
 &#xD;
     &#xD;
    reset[]; &#xD;
    Table[nextFib[], {1000}]; // Timing &#xD;
&#xD;
    (* &#xD;
      ---&amp;gt; {0.01, Null} &#xD;
    *)&#xD;
&#xD;
One problem with persistence created with `Module`-variables is that one should not generally serialize such state (definitions), for example by saving the state via `Save` or `DumpSave`. This is because, the uniqueness of names for `Module`-generated symbols is guaranteed only within a single Mathematica session.&#xD;
&#xD;
&#xD;
`Module` also allows one to create *local functions*, which `With` does not (except pure functions). This is a very powerful capability. It is particularly useful for writing recursive functions, but not only. In the link mentioned above, there were examples of this. One problem with local functions created by `Module` is that these symbols won&amp;#039;t be automatically garbage-collected when `Module` finishes (if they have `DownValues`, `SubValues` or `UpValues`. `OwnValues` are fine), and so may lead to memory leaks. To avoid that, one can `Clear` these symbols inside `Module` before returning the result.&#xD;
&#xD;
##With&#xD;
&#xD;
Use `With` to define local constants, which can not be changed inside the body of your function. &#xD;
&#xD;
###Basic use&#xD;
&#xD;
For example, &#xD;
&#xD;
    f[x_,y_]:=With[{sum = x+y},{sum *x, sum *y}]&#xD;
&#xD;
It is instructive to trace the execution of `f`. You will notice that `sum` gets replaced by its value very early on, before the body starts evaluating. This is quite unlike `Module`, where variable entries get replaced by their values in the process of evaluation, just as it would normally happen were the variables global.&#xD;
&#xD;
###Advanced uses&#xD;
&#xD;
On an advanced level, `With` can be used to inject some evaluated code deep into some expression which is otherwise unevaluated:&#xD;
&#xD;
    With[{x=5},Hold[Hold[x^2]]]&#xD;
&#xD;
    (*&#xD;
        Hold[Hold[5^2]]&#xD;
    *)&#xD;
&#xD;
and is thus an important meta-programming tool. There are lots of uses for this feature, in particular one can use this to inject code into `Compile` at run-time right before compilation. This can extend the capabilities / flexibility of `Compile` quite a bit. One example can be found in my answer to [this][5] question.&#xD;
&#xD;
The semantics of `With` is similar to that of rule substitutions, but an important difference is that `With` cares about inner scoping constructs (during variable name collisions), while rules don&amp;#039;t. Both behaviors can be useful in different situations.&#xD;
&#xD;
###Module vs With&#xD;
&#xD;
Both of these are *lexical* scoping constructs, which means that they bind their variables to lexical their occurrences in the code. Technically, the major difference between them is that  you can not change the values of constants initialized in `With`, in the body of `With`, while you can change values of `Module` variables inside the body. On a deeper level, this is because `With` does not generate any new symbols. It does all the replacements before the body evaluates, and by that time no &amp;#034;constant symbols&amp;#034; are at all present, all of them replaced with their values. `Module`, OTOH, does generate temporary symbols (which are normal symbols with an attribute `Temporary`), which can store a mutable state.&#xD;
&#xD;
Stylistically, it is better to use `With` if you know that your variables are in fact constants, i.e. they won&amp;#039;t change during the code execution. Since `With` does not create extra (mutable) state, the code is cleaner. Also, you have more chances to catch an occasional erroneous attempt in the code to modify such a constant. &#xD;
&#xD;
Performance-wise, `With` tends to be faster than `Module`, because it does not have to create new variables and then destroy them. This however usually only shows up for very light-weight functions. I would not base my preference of one over another on performance boosts.&#xD;
&#xD;
##Block&#xD;
&#xD;
###Basic use&#xD;
&#xD;
`Block` localizes the *value* of the variable. In this example, `a` does not refer to `i` *literally* inside `Block`, but still uses the value set by `Block`.&#xD;
&#xD;
    a:=i&#xD;
    Block[{i=2},a]&#xD;
    {a,i}&#xD;
&#xD;
 `Block` therefore affects the *evaluation stack*, not just the literal occurrences of a symbol inside the code of its body. Its effects are much less local than those of lexical scoping constructs, which makes it much harder to debug programs which use `Block` extensively. It is not much different from using global variables, except that `Block`guarantees that their values will be restored to their previous values once the execution exits `Block` (which is often a big deal). Even so, this non-transparent and non-local manipulation of the variable values is one reason to avoid using `Block` where `With` and / or `Module` can be used. But there are more (see below). &#xD;
&#xD;
&#xD;
In practice, my advice would be to avoid using `Block` unless you know quite well why you need it. It is more error-prone to use it for variable localization than `With` or `Module`, because it does not prevent variable name collisions, and those will be quite hard to debug. One of the reasons people suggest to use `Block` is that they claim it is faster. While it is true, my opinion is that the speed advantage is minimal while the risk is high. I elaborated on this point [here][6], where at the bottom there is also an idiom which allows one to have the best of both worlds. In addition to these reasons, as noted by @Albert Retey, using `Block` with the `Dynamic` - related functionality may lead to nasty surprises, and errors resulting from that may also be quite non-local and hard to find.&#xD;
&#xD;
One valid use of `Block` is to temporarily redefine some global system settings / variables. One of the most common such use cases is when we want to temporarily change the value of &#xD;
&#xD;
    $RecursionLimit&#xD;
&#xD;
or &#xD;
&#xD;
    $IterationLimit &#xD;
&#xD;
variables. Note however that while using &#xD;
&#xD;
    Block[{$IterationLimit = Infinity}, ...] &#xD;
&#xD;
is generally okay, using  &#xD;
&#xD;
    Block[{$RecursionLimit = Infinity}, ...] &#xD;
&#xD;
is not, since the stack space is limited and if it gets exhausted, the kernel will crash. A detailed discussion of this topic and how to make functions tail-recursive in Mathematica, can be found e.g. in my answer to [this question][7].&#xD;
&#xD;
It is quite interesting that the same ability of `Block` can be used to significantly extend the control the user has over namespaces/symbol encapsulation. For example, if you want to load a package, but not add its context to the `$ContextPath` (may be, to avoid shadowing problems), all you have to do is&#xD;
&#xD;
    Block[{$ContextPath}, Needs[Your-package]]&#xD;
&#xD;
As another example, some package you want to load modifies some other function (say, ``System`SomeFunction``), and you want to prevent that without changing the code of the package. Then, you use something like&#xD;
&#xD;
    Block[{SomeFunction}, Needs[That-package]]&#xD;
&#xD;
which ensures that all those modifications did not affect actual definitions for `SomeFunction`  - see [this answer][8] for an example of this.&#xD;
&#xD;
&#xD;
&#xD;
###Advanced uses&#xD;
&#xD;
`Block` is a very powerful metaprogramming device, because you can make every symbol (including system functions) temporarily &amp;#034;forget&amp;#034; what it is (its definitions and other global properties), and this may allow one to change the order of evaluation of an expression involving that symbol(s) in non-trivial ways, which may be hard to achieve by other means of evaluation control (this won&amp;#039;t work on `Locked` symbols). There are many examples of this at work, one which comes to mind now is the `LetL` macro from my answer to [this][9] question. &#xD;
&#xD;
Another more advanced use of `Block` is to ensure that all used variables would be restored to their initial values, even in the case of Abort or exception happening somewhere inside the body of `Block`. In other words, it can be used to ensure that the system will not find itself in an illegal state in the case of sudden failure. If you wrap your critical (global) variables in `Block`, it will guarantee you this.&#xD;
&#xD;
A related use of `Block` is when we want to be sure that some symbols will be cleared at the end. [This question][10] and answers there represent good examples of using `Block` for this purpose.&#xD;
&#xD;
&#xD;
###Variable name conflicts&#xD;
&#xD;
In nested scoping constructs, it may happen that they define variables with the same names. Such conflicts are typically resolved in favor of the inner scoping construct. The documentation contains more details.&#xD;
&#xD;
&#xD;
###Block vs Module/With&#xD;
&#xD;
So, `Block` implements dynamic scoping, meaning that it binds variables in time rather than in space. One can say that a variable localized by `Block` will have its value during the time this `Block` executes (unless further redefined inside of it, of course). I tried to outline the differences between `Block` and `With`/`Module` (dynamic vs lexical scoping) in [this][11]  answer.&#xD;
&#xD;
###Some conclusions&#xD;
&#xD;
 - For most common purposes of variable localization, use `Module`&#xD;
 - For local constants, use `With`&#xD;
 - Do not ordinarily use `Block` for introducing local variables&#xD;
 - All of the scoping constructs under discussion have advanced uses. For `Module` this is mostly creating and encapsulating non-trivial state (persistent or not). For `With`, this is mostly injecting inside unevaluated expressions. For `Block`, there are several advanced uses, but all of them are, well, advanced. I&amp;#039;d be worried if I found myself using `Block` a lot, but there are cases when it is indispensable.&#xD;
 &#xD;
&#xD;
&#xD;
----------&#xD;
&#xD;
&#xD;
  [1]: http://mathematica.stackexchange.com/a/569&#xD;
  [2]: http://community.wolfram.com/web/vitaliyk/home&#xD;
  [3]: http://stackoverflow.com/questions/6661393/mathematica-module-versus-with-or-block-guideline-rule-of-thumb-for-usage&#xD;
  [4]: http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/5eff6213a0ab5f51&#xD;
  [5]: http://stackoverflow.com/questions/4973424/in-mathematica-how-do-i-compile-the-function-outer-for-an-arbitrary-number-of&#xD;
  [6]: http://stackoverflow.com/questions/7596460/condition-block-module-which-way-is-the-most-memory-and-computationally-effi/7597238#7597238&#xD;
  [7]: http://stackoverflow.com/questions/4481301/tail-call-optimization-in-mathematica&#xD;
  [8]: http://stackoverflow.com/questions/4702590/fixing-combinatorica-redefinition-of-element/4720679#4720679&#xD;
  [9]: http://stackoverflow.com/questions/5866016/question-on-condition&#xD;
  [10]: http://stackoverflow.com/questions/7342748/dynamic-programming-in-mathematica-how-to-automatically-localize-and-or-clear/&#xD;
  [11]: http://stackoverflow.com/questions/6236458/plot-using-with-versus-plot-using-block-mathematica/6236808#6236808</description>
    <dc:creator>Leonid Shifrin</dc:creator>
    <dc:date>2017-02-20T10:08:24Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/3495066">
    <title>[WSS25] Visual and statistical analysis of LLMs via problem complexity</title>
    <link>https://community.wolfram.com/groups/-/m/t/3495066</link>
    <description>![Visual and statistical analysis of LLMs via problem complexity][1]&#xD;
&#xD;
&amp;amp;[Wolfram Notebook][2]&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=HeroImage-WSS25.bmp&amp;amp;userId=3492577&#xD;
  [2]: https://www.wolframcloud.com/obj/2bc91532-706a-4dbe-ab99-4446339eba44</description>
    <dc:creator>Rakesh Vijay Kumar</dc:creator>
    <dc:date>2025-07-08T21:23:18Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1421180">
    <title>Rubi - The Rule-based Integrator for Mathematica</title>
    <link>https://community.wolfram.com/groups/-/m/t/1421180</link>
    <description>Two months ago, Albert Rich posted [&amp;#034;What&amp;#039;s the hardest integral Mathematica running Rubi can find?&amp;#034;](http://community.wolfram.com/groups/-/m/t/1343015) here on the Wolfram Community.&#xD;
You might have also seen that I responded in detail, and pointed out a few things that could help improve Rubi (Rule-based integrator).&#xD;
While it appears nothing really happened afterward, this is far from reality.&#xD;
Since then, Albert and I have worked closely together to make Rubi more accessible and user-friendly.&#xD;
If you would like to learn how our productive collaboration evolved, let me invite you to read [my latest blog-post](http://halirutan.de/programming/Rubi/).&#xD;
However, here, we want to share an update that should serve as an overview of what we have done to improve Rubi.&#xD;
&#xD;
First of all, Rubi has got a new home under [rulebasedintegration.org](https://rulebasedintegration.org/), and its old website will no longer be updated.&#xD;
On the new website, you will find information, installation instructions, and links to the source-code and test-suites.&#xD;
&#xD;
Secondly, we created a [Rubi Organization](https://github.com/RuleBasedIntegration) on GitHub that serves as the headquarters for all things Rubi.&#xD;
It contains all Rubi&amp;#039;s code, notebooks, and test-suites nicely structured into several repositories.&#xD;
At the moment, we provide repositories for the&#xD;
&#xD;
* loadable package files and notebook source files defining over 6700 integration rules,&#xD;
* PDF files displaying the rules in human-readable mathematical notation alongside the Mathematica code, and&#xD;
* test-suite files containing over 71000 integration problems and their solutions.&#xD;
&#xD;
The integration test files are available in the syntax used by 4 popular computer algebra systems (Mathematica, Maple, Maxima, and Axiom).&#xD;
The test-suite can be used to compare Rubi&amp;#039;s results with other symbolic integrators, including Mathematica&amp;#039;s `Integrate` function.&#xD;
&#xD;
In addition to the transition to GitHub, we recently released version 4.16.0.3 of Rubi which significantly expands the class of expressions the system can integrate.&#xD;
But the most noticeable change for users is the completely reworked display of the rules and intermediate steps Rubi uses to integrate expressions.&#xD;
Although installation, usage, and examples are given on [Rubi&amp;#039;s website](https://rulebasedintegration.org/), let me show you how easy it is to install and run Rubi 4.16.0.3 using Mathematica 11.3:&#xD;
&#xD;
The command&#xD;
&#xD;
    PacletInstall[&amp;#034;https://github.com/RuleBasedIntegration/Rubi/releases/download/4.16.0.3/Rubi-4.16.0.3.paclet&amp;#034;];&#xD;
&#xD;
installs the Rubi-4.16.0.3 paclet on your computer.&#xD;
After that, to load Rubi into Mathematica all you have to do is issue the `Get` command&#xD;
&#xD;
    &amp;lt;&amp;lt; Rubi`&#xD;
&#xD;
Then to integrate an expression with respect to a variable, use Rubi&amp;#039;s `Int` command similar to Mathematica&amp;#039;s `Integrate` command.  For example, evaluating&#xD;
&#xD;
    Int[(Sec[x]^2 + Sec[x]^2*Tan[x])/((2 - Tan[x])*Sqrt[1 + Tan[x]^3]), x]&#xD;
&#xD;
returns the antiderivative (a.k.a. the indefinite integral)&#xD;
&#xD;
![enter image description here][1]&#xD;
&#xD;
Rubi&amp;#039;s unique ability to display the steps it uses to integrate expressions is a great feature of the system.&#xD;
For example, the `Steps` command&#xD;
&#xD;
    Steps@Int[(Sec[x]^2 + Sec[x]^2*Tan[x])/((2 - Tan[x])*Sqrt[1 + Tan[x]^3]), x]&#xD;
&#xD;
displays&#xD;
&#xD;
![enter image description here][2]&#xD;
&#xD;
Here, in red are the rules used to integrate the expression, and in blue are the intermediate results.&#xD;
Each rule can be expanded to show the rule number, which directly corresponds to the index of the rule in `Int`&amp;#039;s list of DownValues.&#xD;
More importantly, you can see the conditions that have to be satisfied so the rule can be applied.&#xD;
&#xD;
![enter image description here][3]&#xD;
&#xD;
Rubi&amp;#039;s `Stats` command provides statistics about the integration. For example,&#xD;
&#xD;
    Stats[Int[(Sec[x]^2 + Sec[x]^2*Tan[x])/((2 - Tan[x])*Sqrt[1 + Tan[x]^3]), x]]&#xD;
&#xD;
displays&#xD;
&#xD;
![enter image description here][4]&#xD;
&#xD;
The leaf-count size of an antiderivative is a crude measure of its complexity.&#xD;
As you can see, Rubi&amp;#039;s antiderivative for this integral has a leaf-count of 25.&#xD;
Now compare Rubi&amp;#039;s antiderivative with that produced by Mathematica 11.3 for the same integral:&#xD;
&#xD;
    Integrate[(Sec[x]^2 + Sec[x]^2*Tan[x])/((2 - Tan[x])*Sqrt[1 + Tan[x]^3]), x]&#xD;
&#xD;
![enter image description here][5]&#xD;
&#xD;
    LeafCount[%]&#xD;
    (*  290 *)&#xD;
&#xD;
Note that not only is Mathematica&amp;#039;s result more than 11 times the size of Rubi&amp;#039;s, it unnecessarily involves elliptic integral functions *and* the imaginary unit.&#xD;
&#xD;
Skeptics might be inclined to ask if Rubi&amp;#039;s dramatically simpler result is actually a valid antiderivative.&#xD;
Since symbolic differentiation is much easier than integration, antiderivatives can be verified correct by seeing if its derivative equals the original integrand as follows:&#xD;
&#xD;
    expr = (Sec[x]^2 + Sec[x]^2*Tan[x])/((2 - Tan[x])*Sqrt[1 + Tan[x]^3]);&#xD;
    FullSimplify[D[Int[expr, x], x] == expr]&#xD;
    FullSimplify[D[Integrate[expr, x], x] == expr]&#xD;
&#xD;
![enter image description here][6]&#xD;
&#xD;
As you can see Mathematica easily verifies Rubi&amp;#039;s antiderivative correct, but has a hard time verifying its own antiderivative correct...&#xD;
&#xD;
Albert and I are working on publishing the program used to thoroughly test each new version of Rubi before being released.&#xD;
The test program ensures Rubi&amp;#039;s result equals the optimal antiderivative for the over 71000 problems in the test-suite.&#xD;
And yes, the optimal antiderivatives have all been verified correct by differentiation.&#xD;
&#xD;
Of course, the optimal antiderivatives stored in the test-suite are actually just the simplest ones found so far.&#xD;
If you should find a substantially simpler antiderivative than the one in the test-suite, please report it so the test-suite can be made even harder on Rubi!&#xD;
&#xD;
If all that has got you interested in joining Rubi&amp;#039;s community of users, check out its website or talk to us in our [Gitter chatroom](https://gitter.im/Rule-Based-Integration/Lobby).&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=10564sSs5M.png&amp;amp;userId=11733&#xD;
  [2]: https://community.wolfram.com//c/portal/getImageAttachment?filename=qDtIH.png&amp;amp;userId=11733&#xD;
  [3]: https://community.wolfram.com//c/portal/getImageAttachment?filename=vQ4GR.png&amp;amp;userId=11733&#xD;
  [4]: https://community.wolfram.com//c/portal/getImageAttachment?filename=43t8e.png&amp;amp;userId=11733&#xD;
  [5]: https://community.wolfram.com//c/portal/getImageAttachment?filename=xjKTJ.png&amp;amp;userId=11733&#xD;
  [6]: https://community.wolfram.com//c/portal/getImageAttachment?filename=eCoWB.png&amp;amp;userId=11733</description>
    <dc:creator>Patrick Scheibe</dc:creator>
    <dc:date>2018-08-24T02:50:37Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1330785">
    <title>Playing with Gilpin&amp;#039;s Proposal for Advection-based Cryptographic Hashing</title>
    <link>https://community.wolfram.com/groups/-/m/t/1330785</link>
    <description>*WOLFRAM MATERIALS for the ARTICLE:*&#xD;
&#xD;
&amp;gt; William Gilpin. *Cryptographic hashing using chaotic hydrodynamics*.&#xD;
&#xD;
&amp;gt; Proceedings of the National Academy of Sciences, 115 (19) (2018), pp. 4869-4874.&#xD;
&#xD;
&amp;gt; https://doi.org/10.1073/pnas.1721852115&#xD;
&#xD;
&amp;gt; [Full article in PDF][1]&#xD;
&#xD;
&#xD;
![enter image description here][2]&#xD;
&#xD;
##Introduction##&#xD;
&#xD;
Last week, William Gilpin published a fascinating paper suggesting a physics-based hashing mechanism in the Proceedings of the National Society: Cryptographic hashing using chaotic hydrodynamics: https://doi.org/10.1073/pnas.1721852115&#xD;
&#xD;
The paper discusses a hashing algorithm based on fluid mechanics: Particles are distributed in a 2D disk. The inside of the disk is filled with an idealized fluid and the fluid is now stirred with a single stirrer. The stirring process is modelled with two possible stirrer positions. A message (say made from 0s and 1s) can now be encoded through which of the two stirrer positions is active. If the bit from the message is 1, use stirrer position 1, if the bit of the message is 0, use stirrer position 2. After some bites are processed, and the fluid is stirred, this process mixes the particles. Dropping some of the information content of the actual particle positions, e.g. by taking only the x-positions of the particle positions allows to build a hash by using the particle indices after sorting the particles along the x-axis.&#xD;
&#xD;
The Methods section of the paper mentions that all calculations were carried out using Mathematica 11.0. Unfortunately no notebook supplement was given. So,  playing around with ideas of the paper, I re-implemented some of the computations of the paper.&#xD;
&#xD;
The paper is behind a paywall, but fortunately the author&amp;#039;s website has a downloadable copy of the paper [here][3].&#xD;
&#xD;
The potential importance of physics-based models for hashing, and so for cryptocurrencies was pointed out at various sites (e.g. [Stanford News][4], [btcmanager][5]).&#xD;
&#xD;
It is fun to play around with the model.&#xD;
&#xD;
##The chaotic advection model model##&#xD;
&#xD;
This classic model goes back to Hassan Aref  (whom I was fortunate to know personally) from his 1984 paper [Stirring by chaotic advection][6].&#xD;
&#xD;
The Hamiltonian for the movement of a particle with coordinates {ξ,η} in a circle of radius a under the influence of agitating vortex at {x,y} (possibly time-dependent) of strength Γ and its mirror vortex.&#xD;
&#xD;
        H[{ξ_, η_}, {x_, y_}] = &#xD;
          Γ/(2 π) Log[ComplexExpand[ Abs[((ξ + I η) - (x + I y))/((ξ + I η) - a^2/( x - I y))]] ]&#xD;
&#xD;
![enter image description here][7]&#xD;
&#xD;
 The resulting equations of motion:&#xD;
&#xD;
    odes = {ξ&amp;#039;[t] == -D[H[{ξ[t], η[t]}, {x[t], y[t]}], η[t]],&#xD;
                η&amp;#039;[ t] == +D[H[{ξ[t], η[t]}, {x[t], y[t]}], ξ[t]]} // Simplify&#xD;
![enter image description here][8]&#xD;
&#xD;
Solve the equations of motion for randomly selected parameters and plot the particle trajectory. For a position-independent and time-independent vortex, the particle moves in a circle.&#xD;
&#xD;
    nds = NDSolveValue[{&#xD;
       Block[{a = 1, Γ = 1, x = 0.5 &amp;amp;, y = 0 &amp;amp;}, odes],&#xD;
                     ξ[0] == 0.3, η[0] == -0.4}, {ξ[t], η[t]}, {t, 0, 10}]&#xD;
![enter image description here][9]&#xD;
&#xD;
    ParametricPlot[Evaluate[nds], {t, 0, 10}]&#xD;
&#xD;
![enter image description here][10]&#xD;
&#xD;
Here the vortex moves around in a periodic manner. The resulting particle trajectory has a high degree of symmetry.&#xD;
&#xD;
    nds2 = NDSolveValue[{&#xD;
       Block[{a = 1, Γ = 1, x = 0.8 Cos[2 Pi #/200] &amp;amp;, y = 0.8 Sin[2 Pi #/200] &amp;amp;}, odes],&#xD;
                     ξ[0] == 0.3, η[0] == -0.4}, {ξ[t], η[t]}, {t, 0, 400}]&#xD;
&#xD;
![enter image description here][11]&#xD;
&#xD;
    ParametricPlot[Evaluate[nds2], {t, 0, 400}, PlotPoints -&amp;gt; 400]&#xD;
&#xD;
![enter image description here][12]&#xD;
&#xD;
Letting the vortex move along  a random curve results in a chaotic movement of the particle. We color the particle&amp;#039;s trajectory with time.&#xD;
&#xD;
    (* vortex movement curve *)&#xD;
    randomCurve = BSplineFunction[RandomPoint[Disk[], {100}]]; &#xD;
    &#xD;
    X[t_Real] := randomCurve[t/100][[1]]&#xD;
    Y[t_Real] := randomCurve[t/100][[2]]&#xD;
&#xD;
    nds2 = NDSolveValue[{&#xD;
       Block[{a = 1, Γ = 10, x = X, y = Y}, odes],&#xD;
                     ξ[0] == 0.3, η[0] == -0.4}, {ξ[t], η[t]}, {t, 0, 100}]&#xD;
&#xD;
![enter image description here][13]&#xD;
&#xD;
    ParametricPlot[Evaluate[nds2], {t, 0, 100}, PlotPoints -&amp;gt; 1000, &#xD;
     ColorFunction -&amp;gt; Function[{x, y, u}, ColorData[&amp;#034;DarkRainbow&amp;#034;][u]]]&#xD;
&#xD;
![enter image description here][14]&#xD;
&#xD;
Having two possible positions of the vortex and switching periodically between them results in a particle trajectory that is made of piecewise circle arcs.&#xD;
&#xD;
    nds2 = NDSolveValue[{&#xD;
        Block[{a = 1, Γ = 10, x = Sign[Sin[Pi #]]/2 &amp;amp;, y = 0 &amp;amp;}, odes],&#xD;
                      ξ[0] == 2/3, η[0] == 0}, {ξ[t], η[t]}, {t, 0, 100}];&#xD;
    &#xD;
    ParametricPlot[Evaluate[nds2], {t, 0, 100}, PlotPoints -&amp;gt; 1000, &#xD;
     ColorFunction -&amp;gt; Function[{x, y, u}, ColorData[&amp;#034;DarkRainbow&amp;#034;][u]]]&#xD;
&#xD;
![enter image description here][15]&#xD;
&#xD;
Using initially 4320 points on a circle shows how the initial circle gets stretched and ripped apart and the points distribute chaotically over the disk.&#xD;
&#xD;
    nds2 = NDSolveValue[{&#xD;
        Block[{a = 1, Γ = 10, x = Sign[Sin[Pi #]]/2 &amp;amp;, y = 0 &amp;amp;}, odes],&#xD;
                      ξ[0] == Table[2/3 Cos[φ], {φ, 0, 2 Pi, 2 Pi/(12 360)}], &#xD;
                      η[0] == Table[2/3 Sin[φ], {φ, 0, 2 Pi, 2 Pi/(12 360)}]},&#xD;
       {ξ[t], η[t]}, {t, 0, 2}];&#xD;
    &#xD;
    GraphicsGrid[&#xD;
     Partition[Graphics[{LightGray, Disk[], Black, PointSize[0.005], &#xD;
          Point[Transpose[nds2 /. t -&amp;gt; #]]}, ImageSize -&amp;gt; 120] &amp;amp; /@Range[0, 2, 2/19] , 5]]&#xD;
![enter image description here][16]&#xD;
&#xD;
With time running upwards, here is a 3D image of this stirring process. The transition from using the right stirrer to using the left stirrer at time 1 is clearly visible.&#xD;
&#xD;
    trajectories3D = &#xD;
      Transpose[Table[ Append[#, N[τ]] &amp;amp; /@ Transpose[nds2 /. t -&amp;gt; τ], {τ, 0, 2, 2/100}]];&#xD;
    &#xD;
    Graphics3D[{Thickness[0.001], Opacity[0.2], &#xD;
      BSplineCurve /@ RandomSample[trajectories3D, 1600]},&#xD;
                              PlotRange -&amp;gt; All, Axes -&amp;gt; True, BoxRatios -&amp;gt; {1, 1, 2}]&#xD;
&#xD;
![enter image description here][17]&#xD;
&#xD;
Here is the corresponding interactive demonstration.&#xD;
&#xD;
    Manipulate[&#xD;
    Graphics[{LightGray, Disk[], Black, PointSize[0.005], Point[Transpose[nds2 /. t -&amp;gt; τ]]}], &#xD;
    {τ, 0, 2, Appearance -&amp;gt; &amp;#034;Labeled&amp;#034;}]&#xD;
&#xD;
![enter image description here][18]&#xD;
&#xD;
The x-position of the particles will be used later. Here is a plot of the x-positions of 540 points initially on a circle over time.One observes many crossing of these x-trajectories.&#xD;
&#xD;
    nds2B = NDSolveValue[{&#xD;
        Block[{a = 1, Γ = 4, x = Sign[Sin[Pi #]]/2 &amp;amp;, y = 0 &amp;amp;}, odes],&#xD;
                      ξ[0] == Table[2/3 Cos[φ], {φ, 0, 2 Pi, 2 Pi/540}], &#xD;
                      η[0] == Table[2/3 Sin[φ], {φ, 0, 2 Pi, 2 Pi/540}]},&#xD;
       {ξ[t], η[t]}, {t, 0, 12}];&#xD;
    &#xD;
    ListLinePlot[Transpose[Table[{t, #} &amp;amp; /@ nds2B[[1]], {t, 0., 4, 4/200}] ], &#xD;
     PlotStyle -&amp;gt; Table[Directive[Opacity[0.4], Thickness[0.001], ColorData[&amp;#034;DarkRainbow&amp;#034;][j/541]], {j, 541}],&#xD;
     Frame -&amp;gt; True, Axes -&amp;gt; False, FrameLabel -&amp;gt; {t, x}]&#xD;
&#xD;
![enter image description here][19]&#xD;
&#xD;
Using a Dynamic[particleGraphics] we can easily model many more particles in real time without having to store large interpolating functions. We solve the the equations of motion over small time increments and the graphic updates dynamically.&#xD;
&#xD;
    rPoints = Select[Flatten[Table[N[{x, y}], {x, -1, 1, 2/101}, {y, -1, 1, 2/101}], 1], Norm[#] &amp;lt; 1 &amp;amp;]; &#xD;
    &#xD;
    Dynamic[Graphics[{LightGray, Disk[], Black, PointSize[0.001], Point[rPoints]}]]&#xD;
&#xD;
![enter image description here][20]&#xD;
&#xD;
    rhsξ[X_, ξ_List, η_List] := With[{ Γ = 5}, -(((1 - X^2) Γ η (1 + X^2 - 2 X ξ))/(2 π (X^2 + η^2 - 2 X ξ + ξ^2) (1 - 2 X ξ + X^2 (η^2 + ξ^2))))]&#xD;
    rhsη[X_, ξ_List, η_List] := With[{ Γ =  5}, -(((1 - X^2) Γ (-ξ - X^2 ξ +  X (1 - η^2 + ξ^2)))/(2 π (X^2 + η^2 - 2 X ξ + ξ^2) (1 - 2 X ξ + X^2 (η^2 + ξ^2))))]&#xD;
    &#xD;
    With[{Δt = 10^-2, T = 0.2},&#xD;
     Monitor[&#xD;
      Do[&#xD;
       nds = NDSolveValue[&#xD;
          Block[{ X = Evaluate[1/2 Sign[Sin[Pi (k + 1/2) Δt/T]]] &amp;amp;},&#xD;
                   {ξ&amp;#039;[t] == rhsξ[t, ξ[t], η[t]], η&amp;#039;[t] == rhsη[t, ξ[t], η[t]],&#xD;
                    ξ[k Δt] == Transpose[rPoints][[1]], &#xD;
                    η[k Δt] == Transpose[rPoints][[2]]}],&#xD;
          {ξ[t], η[t]}, {t, (k + 1) Δt, (k + 1) Δt}] /. t -&amp;gt; (k + 1) Δt;&#xD;
       rPoints = Transpose[nds],&#xD;
       {k, 0, 200}], k]]&#xD;
&#xD;
Switching irregularly between the two stirrer positions gives qualitatively similar-looking trajectories. We use a sum of three trig functions see here for a detailed account on this type of function).&#xD;
&#xD;
    (* left or right stirrer is on *)&#xD;
    Plot[Sign[Sin[Pi t] + Sin[Pi Sqrt[2] t] + Sin[Pi Sqrt[3] t]], {t, 0, 100}, Exclusions -&amp;gt; None]&#xD;
&#xD;
![enter image description here][21]&#xD;
&#xD;
    nds3 = NDSolveValue[{&#xD;
        Block[{a = 1, Γ = 10, &#xD;
          x = Sign[Sin[Pi #] + Sin[Pi Sqrt[2] #] + Sin[Pi Sqrt[3] #]]/2 &amp;amp;, &#xD;
          y = 0 &amp;amp;}, odes],    ξ[0] == 2/3, η[0] == 0}, {ξ[t], η[t]}, {t, 0, 100}];&#xD;
    &#xD;
    ParametricPlot[Evaluate[nds3], {t, 0, 100}, PlotPoints -&amp;gt; 1000, &#xD;
     ColorFunction -&amp;gt; Function[{x, y, u}, ColorData[&amp;#034;DarkRainbow&amp;#034;][u]]]&#xD;
![enter image description here][22]&#xD;
&#xD;
We can also change the stirring direction.&#xD;
&#xD;
    nds3B = NDSolveValue[{&#xD;
        Block[{a = 1, Γ = 10 Sign[Sin[Pi t] + Sin[Pi Sqrt[2] t] + Sin[Pi Sqrt[3] t]],&#xD;
          x = Sign[Sin[Pi #] + Sin[Pi Sqrt[2] #] + Sin[Pi Sqrt[3] #]]/2 &amp;amp;, &#xD;
          y = 0 &amp;amp;}, odes],    ξ[0] == 2/3, η[0] == 0}, {ξ[t], η[&#xD;
         t]}, {t, 0, 100}];&#xD;
    &#xD;
    ParametricPlot[Evaluate[nds3B], {t, 0, 100}, PlotPoints -&amp;gt; 1000, &#xD;
     ColorFunction -&amp;gt; Function[{x, y, u}, ColorData[&amp;#034;DarkRainbow&amp;#034;][u]]]&#xD;
&#xD;
![enter image description here][23]&#xD;
&#xD;
Here are three stirrer positions at the vertices of an equilateral triangle.&#xD;
&#xD;
    st3[t_] = Piecewise[&#xD;
       With[{r = RandomInteger[{0, 2}]}, {1/2. {Cos[2 Pi r/3], Sin[2 Pi r/3]}, #[[1]] &amp;lt;= t &amp;lt;= #[[2]] }] &amp;amp; /@ &#xD;
        Partition[FoldList[Plus, 0, RandomReal[{0, 1}, 300]], 2, 1]];&#xD;
    &#xD;
    x3[t_Real] := st3[t][[1]]&#xD;
    y3[t_Real] := st3[t][[2]]&#xD;
    &#xD;
    nds3 = NDSolveValue[{ Block[{a = 1, Γ = 5, x = x3, y = y3}, odes], ξ[0] == 1/3, η[0] == 0}, {ξ[t], η[t]}, {t, 0, 100}]&#xD;
&#xD;
![enter image description here][24]&#xD;
&#xD;
    ParametricPlot[Evaluate[nds3], {t, 0, 100}, PlotPoints -&amp;gt; 1000, &#xD;
     ColorFunction -&amp;gt; Function[{x, y, u}, ColorData[&amp;#034;DarkRainbow&amp;#034;][u]]]&#xD;
&#xD;
![enter image description here][25]&#xD;
&#xD;
##Side note: the linked twist map##&#xD;
&#xD;
Mathematically, alternating left and right use of the stirrer, is isomorphic to a so-called linked twist map. The following implements a simple realization of a linked twist map from Cairns /Kolganova.  https://doi.org/10.1088/0951-7715/9/4/011&#xD;
&#xD;
    Clear[g, h, f]; &#xD;
    g[{x_, y_}] := {x, Mod[Piecewise[{{y + 4 x, Abs[x] &amp;lt;= 1/4}}, y], 1, -1/2]}&#xD;
    h[{x_, y_}] := {Mod[Piecewise[{{x + 4 y, Abs[y] &amp;lt;= 1/4}}, x], 1, -1/2], y}&#xD;
    f[{x_, y_}] := g[h[{x, y}]] &#xD;
&#xD;
    f[{x, y}]&#xD;
&#xD;
![enter image description here][26]&#xD;
&#xD;
In explicit piecewise form, the map is more complicated. (To fit it, we use a reduce size.)&#xD;
&#xD;
    (f2 = PiecewiseExpand[# , -1/2 &amp;lt; x &amp;lt; 1/2 &amp;amp;&amp;amp; -1/2 &amp;lt; y &amp;lt; 1/2] &amp;amp; /@ f[{x, y}]) &#xD;
&#xD;
![enter image description here][27]&#xD;
&#xD;
Here are the first and second component visualized.&#xD;
&#xD;
    {ContourPlot[Evaluate[f2[[1]]], {x, -1/2, 1/2} , {y, -1/2, 1/2}, &#xD;
      Exclusions -&amp;gt; {}, PlotPoints -&amp;gt; 60],&#xD;
     ContourPlot[Evaluate[f2[[2]]], {x, -1/2, 1/2} , {y, -1/2, 1/2}, &#xD;
      Exclusions -&amp;gt; {}, PlotPoints -&amp;gt; 60]}&#xD;
&#xD;
![enter image description here][28]&#xD;
&#xD;
Applying the linked twist map to a set of points inside a square hints at the ergodic nature of the map.&#xD;
&#xD;
    ptsRG = With[{pp = 80}, Table[{RGBColor[x + 1/2, y + 1/2, 0.5], Point[{x, y}]}, {y, -1/2, 1/2, 1/pp}, {x, -1/2, 1/2, 1/pp}]];&#xD;
    &#xD;
    Graphics /@ NestList[Function[p, p /. Point[xy_] :&amp;gt; Point[f@xy]], ptsRG, 3]&#xD;
&#xD;
![enter image description here][29]&#xD;
&#xD;
##Closed form mapping##&#xD;
&#xD;
As mentioned, for a fixed stirrer position, a particle moves along a circle. This means that to move the particle to its final position, we don&amp;#039;t have to solve nonlinear differential equations, but rather can calculate the final position through algebraic computations which are unfortunately not fully explicit. Doing the calculations (see Aref&amp;#039;s paper for details) shows that we will have to solve of transcendental equation.&#xD;
&#xD;
In the following we will use a unit disk of radius 1 and a unit strength vortex. The particle is initially at {r,θ} (in polar coordinates) and the stirrer is at {±b,0}.&#xD;
&#xD;
    a = 1;&#xD;
    Γ = 1; &#xD;
&#xD;
The circle the particle is moving on.&#xD;
&#xD;
    circle[{r_, θ_}, b_] :=&#xD;
     Module[{λ, ξc, ρ},&#xD;
      λ = Sqrt[(b^2 + r^2 - 2 b r Cos[θ])/(a^4/b^2 + r^2 - 2 a^2 r Cos[θ]/b)];&#xD;
      ξc = (b - λ^2 a^2/b)/(1 - λ^2);&#xD;
      ρ = Abs[λ/(1 - λ^2) (a^2/b - b)];&#xD;
      Circle[{ξc, 0}, ρ]]&#xD;
&#xD;
 &#xD;
&#xD;
The period for one revolution on the circle.&#xD;
&#xD;
    period[{r_, θ_}, b_, T_] :=  &#xD;
     Module[{λ, ρ, Tλ},&#xD;
      λ = Sqrt[(b^2 + r^2 - 2 b r Cos[θ])/(a^4/b^2 + r^2 - 2 a^2 r Cos[θ]/b)]; &#xD;
      ρ = Abs[λ/(1 - λ^2) (a^2/b - b)]; &#xD;
      Tλ = (2 Pi)^2 ρ^2/Γ (1 + λ^2)/(1 - λ^2) ]&#xD;
&#xD;
The final position after rotating for time T.&#xD;
&#xD;
    rotate[{r_, θ_}, b_, T_, opts___] := &#xD;
    Module[{(*λ,ξc,ρ,θp,Tλ,eq,fr*)},&#xD;
    λ = Sqrt[(b^2 + r^2 - 2 b r Cos[θ])/(a^4/b^2 + r^2 - 2 a^2 r Cos[θ]/b)];&#xD;
    ξc = (b - λ^2 a^2/b)/(1 - λ^2);&#xD;
    ρ = Abs[λ/(1 - λ^2) (a^2/b - b)];&#xD;
    θp = ArcTan[r Cos[θ] - ξc, r Sin[θ]];&#xD;
    Tλ = (2 Pi)^2 ρ^2/Γ (1 + λ^2)/(1 - λ^2);&#xD;
    (* the implicit equation to be solved numerically for θt *)&#xD;
    &#xD;
    eq = θt - 2 λ/(1 + λ^2) Sin[θt] == θp - 2 λ/(1 + λ^2) Sin[θp] + 2 Pi T/Tλ;&#xD;
    fr = FindRoot[eq, {θt, θp}, opts] // Quiet;  (* could use Solve[eq, θt, Reals] *)&#xD;
    {Sqrt[ρ^2 + ξc^2 + 2 ρ ξc Cos[θt]],&#xD;
    ArcTan[ρ Cos[θt] + ξc, ρ Sin[θt]]} /. fr] &#xD;
&#xD;
A high-precision version for later use.&#xD;
&#xD;
     rotateHP[{r_, θ_}, b_, T_ ] :=   &#xD;
     With[{prec = Precision[{r, θ}]}, &#xD;
      rotate[{r, θ}, b, T, WorkingPrecision -&amp;gt; Min[prec, 200] - 1,  PrecisionGoal -&amp;gt; prec - 10]]&#xD;
    &#xD;
    rotateHP[{2/5, 1}, 1/2, 10^-10]&#xD;
&#xD;
    {0.3999999999735895736749310453217879335729586969724148186668989989685300449569453838180010833652353802304511654926113687832716502416432363896855780225351918314742068365263060199921670958293439964299441, &#xD;
    1.000000000034865509829422032384759003150106866109371061507406908121303212377635808764825759934117372434662086592066738925787825280696681907390281734196810440241159138906978471624124765879791828431390}&#xD;
&#xD;
Also for later use, rotate many points at once.&#xD;
&#xD;
    rotate[l : {_List ..}, b_, T_ ] := rotate[#, b, T] &amp;amp; /@ l&#xD;
    &#xD;
    rotateHP[l : {_List ..}, b_, T_ ] := rotateHP[#, b, T] &amp;amp; /@ l&#xD;
&#xD;
The locator is the initial particle position; the stirrer position is the purple point. We show the circle and the final particle position (gray point).&#xD;
&#xD;
    Manipulate[&#xD;
     Graphics[{LightGray, Disk[], &#xD;
       Purple, PointSize[0.02], Point[{b, 0}] , &#xD;
       Gray, circle[ToPolarCoordinates[p], b] ,&#xD;
       PointSize[0.01],&#xD;
       Point[p], Blue , &#xD;
       Point[ FromPolarCoordinates[ rotate @@ SetPrecision[ {ToPolarCoordinates[p], b, T}, 200] ]]}],&#xD;
     {{T, 0.2}, 0.001, 10},&#xD;
     {{b, 0.5}, -0.999, 0.999},&#xD;
     {{p, {0.3, 0.4}}, Locator}]&#xD;
&#xD;
![enter image description here][30]&#xD;
&#xD;
Here is a plot of the period for one revolution as a function of the initial position of the particle. The period can get quite large when points are near the boundary of the disk&#xD;
&#xD;
    ParametricPlot3D[{r Cos[θ], r Sin[θ], period[{r, θ}, 1/2, 1]},&#xD;
     {r, 0, 1}, {θ, -Pi, Pi}, BoxRatios -&amp;gt; {1, 1, 0.3},&#xD;
     PlotPoints -&amp;gt; 40, MeshFunctions -&amp;gt; {#3 &amp;amp;}]&#xD;
&#xD;
![enter image description here][31]&#xD;
&#xD;
For the stirrer located at {0.5,0}, here are the possible circles that the particle will move on.&#xD;
&#xD;
    Graphics[Table[circle[{r, θ}, 1/2.] , {r, 1/10, 9/10, 1/10}, {θ, -Pi, Pi, 2 Pi/20}]]&#xD;
&#xD;
![enter image description here][32]&#xD;
&#xD;
We use the closed form of the stirring map to visualize the flow. Here are about 20k points in stripes in the unit disk.  &#xD;
&#xD;
    stripePoints = Select[RandomPoint[Disk[], 40000], Function[xy, Mod[xy[[1]], 0.2] &amp;lt; 0.1]];&#xD;
    &#xD;
    Graphics[{PointSize[0.002], Point[stripePoints]}]&#xD;
&#xD;
![enter image description here][33]&#xD;
&#xD;
We repeatedly stir with the left and then the right stirrer on for time 1.&#xD;
&#xD;
    swirled[1] = rotate[ToPolarCoordinates[stripePoints], 0.5, 1];&#xD;
    &#xD;
    Graphics[{PointSize[0.002], Point[FromPolarCoordinates[swirled[1]]]}]&#xD;
&#xD;
![enter image description here][34]&#xD;
&#xD;
    swirled[2] = rotate[swirled[1], -0.5, 1];&#xD;
    &#xD;
    Graphics[{PointSize[0.002], Point[FromPolarCoordinates[swirled[2]]]}]&#xD;
&#xD;
![enter image description here][35]&#xD;
&#xD;
    swirled[3] = rotate[swirled[2], 0.5, 1];&#xD;
    &#xD;
    Graphics[{PointSize[0.002], Point[FromPolarCoordinates[swirled[3]]]}]&#xD;
&#xD;
![enter image description here][36]&#xD;
&#xD;
    swirled[4] = rotate[swirled[3], -0.5, 1];&#xD;
    &#xD;
    Graphics[{PointSize[0.002], Point[FromPolarCoordinates[swirled[4]]]}]&#xD;
&#xD;
![enter image description here][37]&#xD;
&#xD;
##Now stir and make hashes##&#xD;
&#xD;
We now use two different initial positions of the points: a sunflower-like one and a random one.&#xD;
&#xD;
    randominitialPositions[n_, prec_] := &#xD;
     SortBy[Table[ReIm[RandomReal[{0, 1}, WorkingPrecision -&amp;gt; prec] *&#xD;
         Exp[ I RandomReal[{-Pi, Pi}, WorkingPrecision -&amp;gt; prec]]], {n}], First]&#xD;
    &#xD;
    SeedRandom[1234];&#xD;
    initialPositionsR = randominitialPositions[100, 250];&#xD;
    &#xD;
    Graphics[{LightGray, Disk[],&#xD;
       MapIndexed[Function[{p, pos},&#xD;
        {Red, PointSize[0.002], Point[p], Black, Text[pos[[1]], p]}],&#xD;
       N[initialPositionsR]]}]&#xD;
&#xD;
![enter image description here][38]&#xD;
&#xD;
    sunflower[n_, R_, prec_] := &#xD;
     Table[FromPolarCoordinates[ N[{Sqrt[j/n] R, Mod[2 Pi (1 - 1/GoldenRatio) j, 2 Pi, -Pi]}, prec]], {j, n}]&#xD;
    &#xD;
    Graphics[{LightGray, Disk[], Black, Point[sunflower[1000, 0.9, 20]]}]&#xD;
![enter image description here][39]&#xD;
&#xD;
The message to encode we will tell in the form of a sequence of 0s and 1s. A zero means use the left stirrer position and a 1 means use the right stirrer position. So, we define a stirring process with a given message σ and fixed b and T as follows:&#xD;
&#xD;
    stirringProcess[initialPositions_, bAbs_, T_, σ_List] := &#xD;
      FromPolarCoordinates /@ &#xD;
      FoldList[rotateHP[#1, #2 bAbs, T] &amp;amp;, ToPolarCoordinates /@ initialPositions, 2 σ - 1] &#xD;
&#xD;
Here is a simple message:&#xD;
&#xD;
    message1 = RandomInteger[{0, 1}, 50]&#xD;
&#xD;
     {1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, &#xD;
       1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,1, 0, 1, 0}&#xD;
&#xD;
Now we carry out the corresponding stirring process. (We arbitrarily use b=1/2 and T=1/10.)&#xD;
&#xD;
    sP1 = stirringProcess[initialPositionsR, 1/2, 1/10, message1];&#xD;
&#xD;
To get a feeling for the stirring process, we connect successive positions of each particle with a randomly colored spline interpolation. (Note that the spline interpolation does not exactly represent the particle&amp;#039;s trajectory.)&#xD;
&#xD;
    Graphics[{LightGray, Disk[], Thickness[0.001], &#xD;
      Map[Function[c, {RandomColor[], BSplineCurve[c, SplineDegree -&amp;gt; 5]}], &#xD;
       Transpose[N[Table[sP1[[j]], {j, 50}]]]]}]&#xD;
![enter image description here][40]&#xD;
&#xD;
Now, can we trust these results? We can check by running the stirring process (numerically) backwards.&#xD;
&#xD;
    sP1Rev = stirringProcess[sP1[[-1]], 1/2, -1/10, Reverse[message1]];&#xD;
&#xD;
The so-recovered initial positions agree to at least 80 digits with the original point positions.&#xD;
&#xD;
    sP1Rev[[-1]] - initialPositionsR // Abs // Max // Accuracy&#xD;
&#xD;
    86.9777&#xD;
&#xD;
As mentioned earlier, we define the hashes as the positions of the particles when ordered according to their x-values. So, for a given particle configurations, this is the hash-making function.&#xD;
&#xD;
    makeHash[l_] := Sort[ MapIndexed[{#1, #2[[1]]} &amp;amp;, l]][[All, 2]]&#xD;
&#xD;
Because the hashes are permutations of the particle numberings, the number of hashes grows factorially with the particle number and 58 particles could model a 256 bit hash and 99 particles a 512 bit hash.&#xD;
&#xD;
    {2^256, {57!, 58!}} // N&#xD;
&#xD;
    {1.15792*10^77, {4.05269*10^76, 2.35056*10^78}}&#xD;
&#xD;
    {2^512, {98!, 99!}} // N&#xD;
&#xD;
    {1.34078*10^154, {9.42689*10^153, 9.33262*10^155}}&#xD;
&#xD;
    hashes1 = makeHash /@ sP1;&#xD;
&#xD;
Here is a visualization how the hashes evolve with each stir. The coloring is from blue (1) to 100 (red) of the initial particle numbering.&#xD;
&#xD;
    ArrayPlot[hashes1, ColorFunction -&amp;gt; ColorData[&amp;#034;DarkRainbow&amp;#034;], PlotRange -&amp;gt; {1, 100}]&#xD;
![enter image description here][41]&#xD;
&#xD;
This is how the edit distance of the hashes increases with successive stirrings.&#xD;
&#xD;
    ListPlot[Table[{j, EditDistance[hashes1[[1]], hashes1[[j]]]}, {j, 1, 50}],  Filling -&amp;gt; Axis]&#xD;
![enter image description here][42]&#xD;
&#xD;
Gilpin defines the rearrangement index of a hash as the sum of the absolute difference between neighboring particle indices.&#xD;
&#xD;
    rearrangementIndex[indexList_] := Total[Abs[Differences[indexList]]]&#xD;
&#xD;
Here is the growth rate of the rearrangement index for our just-calculated hashes. &#xD;
&#xD;
    ListPlot[Table[{j, rearrangementIndex[hashes1[[j]]]}, {j, 1, 50}], Filling -&amp;gt; Axis]&#xD;
![enter image description here][43]&#xD;
&#xD;
Let&amp;#039;s make a second message that has one bit flipped, say at position 10.&#xD;
&#xD;
    message2 = MapAt[1 - # &amp;amp;, message1, 10]&#xD;
&#xD;
    {1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0,&#xD;
     0, 1,  1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0}&#xD;
&#xD;
    message1 - message2&#xD;
&#xD;
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &#xD;
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}&#xD;
&#xD;
The resulting particle movements look quite different.&#xD;
&#xD;
    sP2 = stirringProcess[initialPositionsR, 1/2, 1/10, message2];&#xD;
&#xD;
    Graphics[{LightGray, Disk[], Thickness[0.001], &#xD;
      Map[Function[c, {RandomColor[], BSplineCurve[c, SplineDegree -&amp;gt; 5]}], &#xD;
       Transpose[N[Table[sP2[[j]], {j, 50}]]]]}]&#xD;
![enter image description here][44]&#xD;
&#xD;
The edit distances between the two hash sequences increase quickly after the different bit is encountered.&#xD;
&#xD;
    hashes2 = makeHash /@ sP2;&#xD;
&#xD;
    ListPlot[Table[{j, EditDistance[hashes1[[j]], hashes2[[j]]]}, {j, 0, 50}], Filling -&amp;gt; Axis]&#xD;
&#xD;
![enter image description here][45]&#xD;
&#xD;
Gilpin carried out many numerical experiments investigating how the hashes behave as a function of the hash length (number of particles), stirring time T, and message length.&#xD;
&#xD;
The next two examples change only the stirring time, and keep all other parameters: message, stirrer distance, initial particle distance.&#xD;
&#xD;
    sP1B = stirringProcess[initialPositionsR, 1/2, 1/9, message1];&#xD;
&#xD;
    hashes1B = makeHash /@ sP1B;&#xD;
&#xD;
    ListPlot[Table[{j, EditDistance[hashes1[[j]], hashes1B[[j]]]}, {j, 0, 50}], Filling -&amp;gt; Axis]&#xD;
&#xD;
![enter image description here][46]&#xD;
&#xD;
With increasing stirring time, the edit distance between the hashes quickly increases.&#xD;
&#xD;
    sP1C = stirringProcess[initialPositionsR, 1/2, 1/2, message1];&#xD;
    &#xD;
    hashes1C = makeHash /@ sP1C;&#xD;
    &#xD;
    ListPlot[Table[{j, EditDistance[hashes1[[j]], hashes1C[[j]]]}, {j, 0, 50}], Filling -&amp;gt; Axis]&#xD;
![enter image description here][47]&#xD;
&#xD;
Next, we use the phyllotaxis-like initial position from above with 200 particles. We also use a longer stirring time (T=1).&#xD;
&#xD;
    message3 = RandomInteger[{0, 1}, 50]&#xD;
&#xD;
    {0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,1, 0, 1, 0}&#xD;
&#xD;
    sP3 = stirringProcess[sunflower[200, 9/10, 250], 1/2, 1, message3];&#xD;
&#xD;
A plot of the 200 particle trajectories suggests a good mixing.&#xD;
&#xD;
    Graphics[{LightGray, Disk[], Thickness[0.001], &#xD;
      Map[Function[c, {RandomColor[], BSplineCurve[c, SplineDegree -&amp;gt; 5]}], &#xD;
       Transpose[N[Table[sP3[[j]], {j, 50}]]]]}]&#xD;
&#xD;
![enter image description here][48]&#xD;
&#xD;
Already after the first stir, the edit distance between the original hash and the one resulting after stirring is quite large.&#xD;
&#xD;
    hashes3 = makeHash /@ sP3;&#xD;
    &#xD;
    ListPlot[Table[{j, EditDistance[hashes3[[1]], hashes3[[j]]]}, {j, 0, 50}], Filling -&amp;gt; Axis]&#xD;
![enter image description here][49]&#xD;
&#xD;
We will end here. The interested reader can continue to model, stir a million times, count trajectory exchanges, and statistically analyze other aspects of the proposed hashing scheme from Gilpin&amp;#039;s paper. &#xD;
&#xD;
PS: And one can compare with theoretical hashing probabilities for ideal hashes. Such as: draw \[ScriptCapitalN]s hashes from M! possible hashes. How many different hashes Subscript[\[ScriptCapitalN], U] does one draw in average?&#xD;
&#xD;
    uniqueHashes[M_, \[ScriptCapitalN]s_] := &#xD;
     M! (1 - (1 - 1/M!)^\[ScriptCapitalN]s)&#xD;
&#xD;
    Plot3D[uniqueHashes[M, \[ScriptCapitalN]s], {M, 1, 60}, {\[ScriptCapitalN]s, 1, 1000}, MeshFunctions -&amp;gt; {#3 &amp;amp;},&#xD;
     PlotPoints -&amp;gt; 100, ScalingFunctions -&amp;gt; &amp;#034;Log&amp;#034;, PlotRange -&amp;gt; All,&#xD;
     WorkingPrecision -&amp;gt; 50,&#xD;
     AxesLabel -&amp;gt; {Style[&amp;#034;M&amp;#034;, Italic], Style[&amp;#034;\[ScriptCapitalN]s&amp;#034;, Italic], Style[&amp;#034;\!\(\*SubscriptBox[\(\[ScriptCapitalN]\), \(U\)]\)&amp;#034;, Italic]}]&#xD;
&#xD;
![enter image description here][50]&#xD;
&#xD;
For Ns≪M!, this becomes:&#xD;
&#xD;
    Series[Mfac (1 - (1 -  1/Mfac)^\[ScriptCapitalN]s), {Mfac, ∞, 2}] /. Mfac -&amp;gt; M! // Simplify&#xD;
&#xD;
![enter image description here][51]&#xD;
&#xD;
    uniqueHashesApprox[M_, \[ScriptCapitalN]s_] := \[ScriptCapitalN]s - (\[ScriptCapitalN]s*(\[ScriptCapitalN]s - 1))/(2*M!) + (\[ScriptCapitalN]s*(\[ScriptCapitalN]s - 1)*(\[ScriptCapitalN]s - 2))/(6*M!^2)&#xD;
&#xD;
Here is a quick numerical modeling with a sample size of 100 from 6!=720 possible hashes.&#xD;
&#xD;
    With[{M = 6, \[ScriptCapitalN]s = 100},&#xD;
      {Table[Length[&#xD;
          Tally[RandomChoice[Range[M!], \[ScriptCapitalN]s]]], {10000}] // Mean,&#xD;
       uniqueHashes[M, \[ScriptCapitalN]s],&#xD;
       uniqueHashesApprox[M, \[ScriptCapitalN]s]}] // N&#xD;
&#xD;
    {93.407, 93.4267, 93.4369}&#xD;
&#xD;
I definitely suggest reading the whole paper, including the Supplementary Information.&#xD;
&#xD;
The notebook with all the code and visualizations is attached.&#xD;
&#xD;
&#xD;
  [1]: https://www.pnas.org/doi/epdf/10.1073/pnas.1721852115&#xD;
  [2]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2018-05-02at11.55.34AM.png&amp;amp;userId=20103&#xD;
  [3]: http://www.wgilpin.com/papers/gilpin_pnas_2018.pdf&#xD;
  [4]: https://news.stanford.edu/2018/04/23/swirling-liquids-shed-light-bitcoin-works/&#xD;
  [5]: https://btcmanager.com/stanford-university-physicists-uncover-correlation-between-bitcoin-transactions-and-laws-of-nature/&#xD;
  [6]: https://www.cambridge.org/core/journals/journal-of-fluid-mechanics/article/stirring-by-chaotic-advection/7B32CACE61D5AD79077846D7ACF4A31E&#xD;
  [7]: http://community.wolfram.com//c/portal/getImageAttachment?filename=61661.png&amp;amp;userId=20103&#xD;
  [8]: http://community.wolfram.com//c/portal/getImageAttachment?filename=82192.png&amp;amp;userId=20103&#xD;
  [9]: http://community.wolfram.com//c/portal/getImageAttachment?filename=40363.png&amp;amp;userId=20103&#xD;
  [10]: http://community.wolfram.com//c/portal/getImageAttachment?filename=79744.png&amp;amp;userId=20103&#xD;
  [11]: http://community.wolfram.com//c/portal/getImageAttachment?filename=59285.png&amp;amp;userId=20103&#xD;
  [12]: http://community.wolfram.com//c/portal/getImageAttachment?filename=10756.png&amp;amp;userId=20103&#xD;
  [13]: http://community.wolfram.com//c/portal/getImageAttachment?filename=34567.png&amp;amp;userId=20103&#xD;
  [14]: http://community.wolfram.com//c/portal/getImageAttachment?filename=92028.png&amp;amp;userId=20103&#xD;
  [15]: http://community.wolfram.com//c/portal/getImageAttachment?filename=19639.png&amp;amp;userId=20103&#xD;
  [16]: http://community.wolfram.com//c/portal/getImageAttachment?filename=385110.png&amp;amp;userId=20103&#xD;
  [17]: http://community.wolfram.com//c/portal/getImageAttachment?filename=341511.png&amp;amp;userId=20103&#xD;
  [18]: http://community.wolfram.com//c/portal/getImageAttachment?filename=891612.png&amp;amp;userId=20103&#xD;
  [19]: http://community.wolfram.com//c/portal/getImageAttachment?filename=903513.png&amp;amp;userId=20103&#xD;
  [20]: http://community.wolfram.com//c/portal/getImageAttachment?filename=200714.png&amp;amp;userId=20103&#xD;
  [21]: http://community.wolfram.com//c/portal/getImageAttachment?filename=1069415.png&amp;amp;userId=20103&#xD;
  [22]: http://community.wolfram.com//c/portal/getImageAttachment?filename=577216.png&amp;amp;userId=20103&#xD;
  [23]: http://community.wolfram.com//c/portal/getImageAttachment?filename=224217.png&amp;amp;userId=20103&#xD;
  [24]: http://community.wolfram.com//c/portal/getImageAttachment?filename=435818.png&amp;amp;userId=20103&#xD;
  [25]: http://community.wolfram.com//c/portal/getImageAttachment?filename=121819.png&amp;amp;userId=20103&#xD;
  [26]: http://community.wolfram.com//c/portal/getImageAttachment?filename=370620.png&amp;amp;userId=20103&#xD;
  [27]: http://community.wolfram.com//c/portal/getImageAttachment?filename=949421.png&amp;amp;userId=20103&#xD;
  [28]: http://community.wolfram.com//c/portal/getImageAttachment?filename=426622.png&amp;amp;userId=20103&#xD;
  [29]: http://community.wolfram.com//c/portal/getImageAttachment?filename=281923.png&amp;amp;userId=20103&#xD;
  [30]: http://community.wolfram.com//c/portal/getImageAttachment?filename=365024.png&amp;amp;userId=20103&#xD;
  [31]: http://community.wolfram.com//c/portal/getImageAttachment?filename=389825.png&amp;amp;userId=20103&#xD;
  [32]: http://community.wolfram.com//c/portal/getImageAttachment?filename=256626.png&amp;amp;userId=20103&#xD;
  [33]: http://community.wolfram.com//c/portal/getImageAttachment?filename=218327.png&amp;amp;userId=20103&#xD;
  [34]: http://community.wolfram.com//c/portal/getImageAttachment?filename=319828.png&amp;amp;userId=20103&#xD;
  [35]: http://community.wolfram.com//c/portal/getImageAttachment?filename=889929.png&amp;amp;userId=20103&#xD;
  [36]: http://community.wolfram.com//c/portal/getImageAttachment?filename=995130.png&amp;amp;userId=20103&#xD;
  [37]: http://community.wolfram.com//c/portal/getImageAttachment?filename=30s.png&amp;amp;userId=20103&#xD;
  [38]: http://community.wolfram.com//c/portal/getImageAttachment?filename=639031.png&amp;amp;userId=20103&#xD;
  [39]: http://community.wolfram.com//c/portal/getImageAttachment?filename=469232.png&amp;amp;userId=20103&#xD;
  [40]: http://community.wolfram.com//c/portal/getImageAttachment?filename=123233.png&amp;amp;userId=20103&#xD;
  [41]: http://community.wolfram.com//c/portal/getImageAttachment?filename=1074134.png&amp;amp;userId=20103&#xD;
  [42]: http://community.wolfram.com//c/portal/getImageAttachment?filename=497035.png&amp;amp;userId=20103&#xD;
  [43]: http://community.wolfram.com//c/portal/getImageAttachment?filename=993836.png&amp;amp;userId=20103&#xD;
  [44]: http://community.wolfram.com//c/portal/getImageAttachment?filename=852637.png&amp;amp;userId=20103&#xD;
  [45]: http://community.wolfram.com//c/portal/getImageAttachment?filename=597938.png&amp;amp;userId=20103&#xD;
  [46]: http://community.wolfram.com//c/portal/getImageAttachment?filename=1011739.png&amp;amp;userId=20103&#xD;
  [47]: http://community.wolfram.com//c/portal/getImageAttachment?filename=1005540.png&amp;amp;userId=20103&#xD;
  [48]: http://community.wolfram.com//c/portal/getImageAttachment?filename=132941.png&amp;amp;userId=20103&#xD;
  [49]: http://community.wolfram.com//c/portal/getImageAttachment?filename=625642.png&amp;amp;userId=20103&#xD;
  [50]: http://community.wolfram.com//c/portal/getImageAttachment?filename=879343.png&amp;amp;userId=20103&#xD;
  [51]: http://community.wolfram.com//c/portal/getImageAttachment?filename=1026844.png&amp;amp;userId=20103</description>
    <dc:creator>Michael Trott</dc:creator>
    <dc:date>2018-05-02T11:44:45Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/218587">
    <title>Enigma-like machine in Wolfram Language?</title>
    <link>https://community.wolfram.com/groups/-/m/t/218587</link>
    <description>Hi all, one of my friends shared the following link, which I found interesting to share with you and by the way, ask the community if it is to do something like the machine enigma that is on that page, I hope someone has any idea how to do it.&#xD;
&#xD;
[url=http://enigmaco.de/enigma/enigma.swf]http://enigmaco.de/enigma/enigma.swf[/url]</description>
    <dc:creator>Luis Ledesma</dc:creator>
    <dc:date>2014-03-13T23:51:00Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1121273">
    <title>Metaprogramming in Wolfram Language</title>
    <link>https://community.wolfram.com/groups/-/m/t/1121273</link>
    <description>*NOTE:  Please see the original version of this post [**HERE**][1]. Cross-posted here per suggestion of [Vitaliy Kaurov][2]*&#xD;
&#xD;
*Also note: This post has been reposted verbatim, and as such is rather dated. While I believe that it is still mostly accurate, it does not necessarily fully reflect my current views on the subject matter. In particular, a number of newer internal projects have been using metaprogramming techniques in ways not fully reflected here.*&#xD;
&#xD;
----------&#xD;
&#xD;
##What this answer is and is not&#xD;
&#xD;
To avoid some confusion and misunderstanding, let me state right away what is the intended status of this answer.&#xD;
&#xD;
This answer ***is not***&#xD;
&#xD;
 - A tutorial to the subject&#xD;
 - A systematic, or complete, introduction to the subject&#xD;
 - An authoritative answer putting the final word on the subject&#xD;
&#xD;
This answer hopefully is&#xD;
&#xD;
 - An (subjective!) overview of various meta-programming techniques in Mathematica, *in the way they are known to me*. I want to explicitly state that I am ***not*** trying to convey any kind of the &amp;#034;common wisdom&amp;#034; here, since the answer is largely based on my own experiences, and I have not seen an overwhelming number of meta-programming examples in Mathematica-related resources I had a chance to get acquainted with (so I may have no idea what the common wisdom is :)). &#xD;
 - A collection of (hopefully relevant) links with some minimal explanations, which would allow the reader to see some examples and applications of metaprogramming in Mathematica, or at least examples of what I consider meta-programming in Mathematica.&#xD;
 - A possible stub for some future answers, so that this larger one could be eventually rewritten and/or split into more focused and narrow ones, as the interest towards some particular forms of metaprogramming in Mathematica is being developed in our community. &#xD;
&#xD;
&#xD;
&#xD;
##Preamble&#xD;
&#xD;
Ok, let me give it a shot. I&amp;#039;ll start by claiming that Mathematica is very well suited for meta-programming, and one can write much more powerful programs in Mathematica by utilizing it. However, while it *allows* for very interesting and powerful meta-programming techniques, it does not IMO provide a convenient layer of tools to make these techniques more standard and effortless. Particularly painful is the evaluation control (preventing pieces of code from premature evaluation), because of the *absence* of the true quotation mechanism (here I will disagree with some other answers), the infinite evaluation model of Mathematica, and a quite complex core evaluator. &#xD;
&#xD;
&#xD;
##Enumerating some meta-programming techniques&#xD;
&#xD;
There are several forms of meta-programming, so let me give a partial list first, and discuss afterwards&#xD;
&#xD;
 - Introspection-based metaprogramming&#xD;
 - Reflection-based metaprogramming (like in say, Java)&#xD;
 - Run-time code generation&#xD;
 - Macros (like in Lisp)&#xD;
 - DSL (domain-specific-language) creation&#xD;
 - ...?&#xD;
&#xD;
In addition to these, Mathematica has its own meta-programming devices, such as rule-based metaprogramming and the `Block`-related techniques.&#xD;
&#xD;
##Introspection&#xD;
&#xD;
Mathematica is IMO very strong here. There are a couple of reasons for this:&#xD;
&#xD;
 - Homoiconic language (programs written in own data structures - Mathematica expressions. This is code-as-data paradigm, like Lisp which uses lists for this)&#xD;
&#xD;
 - One can access global definitions for symbols stored in `OwnValues`, `DownValues`, `SubValues`, `UpVaulues`, etc, and various other global properties, programmatically.&#xD;
&#xD;
 - Rule-based destructuring techniques (using `Cases` etc) seriously simplify many introspection-related operations&#xD;
&#xD;
 - Mathematica code is &amp;#034;over-transparent&amp;#034; - even pure functions are expressions, available to introspection and destructuring, rather than black boxes. This has its downsides (for example, making a functional abstraction leaky in Mathematica, see the end of [this answer][3]), but it also allows for things like `withGlobalFunctions` macro from [this answer][4], where global function definitions are expanded inside pure functions (that macro also illustrates other meta-programming techniques).&#xD;
&#xD;
###Automatic dependency tracking&#xD;
&#xD;
I will give a single simple explicit example of what I mean by introspection here, and supply some references to more involved cases. The following line of code gives all the symbols used to build a given expression `expr`, kept unevaluated:&#xD;
&#xD;
    Cases[Unevaluated[expr],s_Symbol:&amp;gt;HoldComplete[s],{0,Infinity},Heads-&amp;gt;True]&#xD;
&#xD;
Note that this will work for *any* Mathematica expression, including a piece of (perhaps unevaluated) Mathematica code.&#xD;
&#xD;
A good illustration of introspection-based meta-programming is the symbol dependency analysis. I gave it a shot [here][5], where I fully used all of the above-mentioned features (homoiconic language,  low-level access to symbol&amp;#039;s properties, rule-based destructuring). A simpler but practical application of dependency analysis can be found e.g. in the `getDependencies` function from [this answer][6], where I do use the dependencies to dynamically construct a set of symbols which are encapsulated (not easily available on the top-level) but whose definitions must be saved during the serialization of the list object being constructed.&#xD;
&#xD;
###Working around some language limitations&#xD;
&#xD;
Sometimes, introspection-based metaprogramming can be also used to go around certain limitations of the language, or to make the language constructs behave in the way you want while minimally affecting them. Some examples off the top of my head: [changing the default behavior of `SaveDefinitions` option for `Manipulate`][7],  [making patterns to match only children of certain elements][8], and also two functions from [this answer][9]: a function `casesShielded` which implements a version of `Cases` that shields certain sub-expressions (matching specific pattern) from the pattern-matcher. and a (rather hacky) function `myCases` which implements a modified depth-first search, where the head is inspected before the elements (this is not what is happening in standard `Cases`, which sometimes has unwanted consequences). Yet another example here is the tiny framework I wrote to deal with the leaks of standard lexical scoping mechanism in Mathematica, which can be found [here][10].&#xD;
&#xD;
###Summary&#xD;
&#xD;
To conclude this section, I think that introspection-based meta-programming is a very useful and powerful technique in Mathematica, and the one that is relatively easy to implement without engaging in a fight with the system. I am also positive that it is possible to factor out the most useful introspection primitives and have a higher-level introspection-based metaprogramming library, and hope such a library will emerge soon.&#xD;
&#xD;
##Reflection - based metaprogramming&#xD;
&#xD;
This may probably be considered a subset of the introspection-based metaprogramming, but it is particularly powerful for languages which impose more rigid rules on how code is written, particularly OO languages (Java for example). This uniform and rigid structure (e.g. all code is in classes, etc) allows for automatic querying of, for example, the methods called on the object, etc. Mathematica per se is not particularly powerful  here, because &amp;#034;too many ways of doing things&amp;#034; are allowed for this to be effective, but one can surely write frameworks and / or DSLs in Mathematica which would benefit from this meta-programming style.&#xD;
&#xD;
##Run-time code generation&#xD;
&#xD;
This type of meta-programming can be used relatively easily and brings a lot to the table in Mathematica. &#xD;
&#xD;
###Automation and adding convenient syntax&#xD;
&#xD;
I will give a small example from [this answer][11], where an ability to generate a pure function (closure) at run-time allows us to easily define a version of SQL `select` with a more friendly Mathematica syntax, and based on the in-memory Mathematica representation of an SQL table as a nested list: &#xD;
&#xD;
    ClearAll[select, where];&#xD;
    SetAttributes[where, HoldAll];&#xD;
    select[table : {colNames_List, rows__List}, where[condition_]] :=&#xD;
      With[{selF = Apply[Function, Hold[condition] /.&#xD;
          Dispatch[Thread[colNames -&amp;gt; Thread[Slot[Range[Length[colNames]]]]]]]},&#xD;
      Select[{rows}, selF @@ # &amp;amp;]];&#xD;
&#xD;
Please see the aforementioned answer for examples of use. Further developments of these ideas (also based on meta-programming) can be found in [this][12] and [this][13] discussions. &#xD;
&#xD;
###Making JIT-compiled functions, and using `Compile` in more flexible ways&#xD;
&#xD;
An important class of applications of run-time code-generation is in improving the flexibility of `Compile`. A simple example would be to create a JIT-compiled version of `Select`, which would compile `Select` with a custom predicate:&#xD;
&#xD;
    ClearAll[selectJIT];&#xD;
    selectJIT[pred_, listType_] :=&#xD;
      selectJIT[pred, Verbatim[listType]] = &#xD;
        Block[{lst},&#xD;
         With[{decl = {Prepend[listType, lst]}},&#xD;
          Compile @@ &#xD;
           Hold[decl, Select[lst, pred], CompilationTarget -&amp;gt; &amp;#034;C&amp;#034;, &#xD;
              RuntimeOptions -&amp;gt; &amp;#034;Speed&amp;#034;]]];&#xD;
&#xD;
This function actually illustrates several techniques, but let me first show how it is used:&#xD;
&#xD;
    test = RandomInteger[{-25, 25}, {10^6, 2}];&#xD;
    selectJIT[#[[2]] &amp;gt; 0 &amp;amp;, {_Integer, 2}][test] // Short // AbsoluteTiming &#xD;
    selectJIT[#[[2]] &amp;gt; 0 &amp;amp;, {_Integer, 2}][test] // Short // AbsoluteTiming&#xD;
&#xD;
    (*&#xD;
    &#xD;
     ==&amp;gt; {0.4707032,{{-6,9},{-5,23},{-4,4},{13,3},{-5,7},{19,22},&amp;lt;&amp;lt;489909&amp;gt;&amp;gt;,{11,25},{-6,5},&#xD;
              {-24,1},{-25,18},{9,19},{13,24}}}&#xD;
&#xD;
     ==&amp;gt; {0.1250000,{{-6,9},{-5,23},{-4,4},{13,3},{-5,7},{19,22},&amp;lt;&amp;lt;489909&amp;gt;&amp;gt;,{11,25},{-6,5},&#xD;
              {-24,1},{-25,18},{9,19},{13,24}}}&#xD;
    *)&#xD;
&#xD;
The second time it was several times faster because the compiled function was memoized. But even including the compilation time, it beats the standard `Select` here:&#xD;
&#xD;
    Select[test,#[[2]]&amp;gt;0&amp;amp;]//Short//AbsoluteTiming&#xD;
  &#xD;
    (*&#xD;
      ==&amp;gt; {1.6269531,{{-6,9},{-5,23},{-4,4},{13,3},{-5,7},{19,22},&amp;lt;&amp;lt;489909&amp;gt;&amp;gt;,{11,25},{-6,5},&#xD;
        {-24,1},{-25,18},{9,19},{13,24}}}&#xD;
    *)&#xD;
&#xD;
The other techniques illustrated here are the use of constructs like `Compile@@Hold[...]` to fool the variable-renaming scheme (see e.g. [this answer][14] for a detailed explanation), and the use of `With` and replacement rules (pattern-based definitions) as a code-injecting device (this technique is used very commonly). Another example of a very similar nature is [here][15], and yet another, very elegant example is [here][16].&#xD;
&#xD;
###Custom assignment operators and automatic generation of function&amp;#039;s definitions&#xD;
&#xD;
Another class of run-time code-generation techniques (which is somewhat closer to macros in spirit) is to use custom assignment operators, so that you can generate rather complex or large (possibly boilerplate) code from relatively simple specifications. Applications range from relatively simple cases of adding some convenience/ syntactic sugar, such as e.g. [here][17] (where we define a custom assignment operator to allow us to use option names directly in code), to somewhat more complex cases like making replacements in definitions at the definition-time, as say in the function `lex` from [this answer][18] (see also the code for a `LetL` macro below), to quite sophisticated generation of boilerplate code, happening e.g. in JLink behind the scenes (which, for JLink, is a big deal, because *this* (plus of course the great design of JLink and Java reflection) is the reason why JLink is so much easier to use than Mathlink). &#xD;
&#xD;
###Automating error-handling and generating boilerplate code&#xD;
&#xD;
Yet another use for run-time code generation (similar to the previous) is to automate error-handling. I discussed one approach to that [here][19], but it does not have to stop there - one can go much further in factoring out (and auto-generating) the boilerplate code from the essential code. &#xD;
&#xD;
###A digression: one general problem with various meta-programming techniques in Mathematica&#xD;
&#xD;
The problem with this and previous classes of use cases however is the lack of composition: you can not generally define  several custom assignment operators and be sure that they will always work correctly in combinations. To do this, one has to write a framework, which would handle composition. While this is possible to do, the development effort can rarely be justified for simple projects. Having a general library for this would be great, provided that this is at all possible. In fact, I will argue that the lack of composibility (&amp;#034;out of the box&amp;#034;) is  plaguing many potentially great meta-programming techniques in Mathematica, particularly macros.&#xD;
&#xD;
Note that I don&amp;#039;t consider this being a fundamental core language-level problem, since the relevant libraries / frameworks can surely be written. I view it more as a consequence of the extreme generality of Mathematica and it being in a transition from a niche scientific language to a general-purpose one (in terms of its typical uses, not just capabilities), so I am sure this problem has a solution and will eventually be solved.&#xD;
&#xD;
###Proper (macro-like) run-time generation of Mathematica code &#xD;
&#xD;
A final use case for the run-time code generation I want to mention is, well, run-time Mathematica code generation. This is also similar to macros (as they are understood in Lisp) in spirit, in fact probably the closest to them from all techniques I am describing here. One relatively simple example I discuss [here][20], and a similar approach is described [here][21]. A more complex case involving generation of entire packages I used for the real-time cell-based code highlighter described [here][22]. There are also more sophisticated techniques of run-time Mathematica code generation - one of which (in a very oversimplified form) I described [here][23]&#xD;
&#xD;
###Summary&#xD;
&#xD;
To summarize this section, I view run-time code generation as another meta-programming technique which is absolutely central to make non-trivial things with Mathematica. &#xD;
&#xD;
&#xD;
##Macros&#xD;
&#xD;
First, what I mean by macros is probably not what is commonly understood by macros in other languages. Specifically, by macro in Mathematica I will mean a construct which:&#xD;
&#xD;
 - Manipulates pieces of Mathematica code as data, possibly preventing them from (premature) evaluation&#xD;
 - Expands code at run-time (not &amp;#034;read-time&amp;#034; or &amp;#034;compile-time&amp;#034;, which are not so well defined in Mathematica)&#xD;
&#xD;
###Some simple examples&#xD;
&#xD;
Here is the simplest macro I know of, which allows one to avoid introducing an intermediate variable in cases when something must be done after the result has been obtained:&#xD;
&#xD;
    SetAttributes[withCodeAfter,HoldRest];&#xD;
    withCodeAfter[before_,after_]:=(after;before)&#xD;
&#xD;
The point here is that the argument `before` is computed before being passed in the body of `withCodeAfter`, therefore evaluating to  the result we want, while the code `after` is being passed unevaluated (due to the `HoldRest` attribute), and so is evaluated already inside the body of `withCodeAfter`. Nevertheless, the returned result is the value of `before`, since it stands at the end.&#xD;
&#xD;
Even though the above macro is very simple, it illustrates the power of macros, since this kind of code manipulation requires special support from the language and is not present in many languages.&#xD;
&#xD;
###Tools used for writing macros&#xD;
&#xD;
The main tools used for writing macros are tools of evaluation control, such as&#xD;
&#xD;
 - `Hold*`- attributes, &#xD;
 - `Evaluate` and `Unevaluated`&#xD;
 -  code injection using `With` and / or replacement rules&#xD;
 -  Pure functions with `Hold` - attributes&#xD;
&#xD;
Even in the simple example above, 2 of these tools were used (`Hold`-attribute and replacement rules, the latter hidden a bit by using global replacement rules / definitions). The discussion of the evaluation control constructs proper is outside the scope of the present discussion but a few places you can look at are [here][24] and [here][25]&#xD;
&#xD;
###Typical classes of macros&#xD;
&#xD;
Macros can widely range in their purpose. Here are some typical classes&#xD;
&#xD;
 - Making new scoping constructs or environments (very typical use case)&#xD;
 - Used in combination with run-time code generation to inject some unevaluated code&#xD;
 - Used in combination with some dynamic scoping, to execute code in some environments where certain global rules are modified. In this case, the &amp;#034;macro&amp;#034; - part is used to delay the evaluation until the code finds itself in a new environment, so strictly speaking these are rather custom dynamic scoping constructs.&#xD;
&#xD;
###Examples of new scoping constructs / environments&#xD;
&#xD;
There are plenty of examples of the first type of macros available in the posts on StackOverlflow and here. One of my favorite macros, which I will reproduce here, is the `LetL` macro which allows consecutive bindings for `With` scoping construct:&#xD;
&#xD;
    ClearAll[LetL];&#xD;
    SetAttributes[LetL, HoldAll];&#xD;
    LetL /: Verbatim[SetDelayed][lhs_, rhs : HoldPattern[LetL[{__}, _]]] :=&#xD;
       Block[{With}, Attributes[With] = {HoldAll};&#xD;
         lhs := Evaluate[rhs]];&#xD;
    LetL[{}, expr_] := expr;&#xD;
    LetL[{head_}, expr_] := With[{head}, expr];&#xD;
    LetL[{head_, tail__}, expr_] := &#xD;
      Block[{With}, Attributes[With] = {HoldAll};&#xD;
        With[{head}, Evaluate[LetL[{tail}, expr]]]];&#xD;
&#xD;
What it does is to expand a single declaration like `LetL[{a=1,b=a+1,c = a+b},a+b+c]` into a nested `With` at run-time, and it also works for function definitions. I described in more fully [here][26] (where some subtleties associated with it are also described), and used it extensively e.g. [here][27]. A very similar example can be found in [this answer][28]. Yet another example I already mentioned - it is the macro `withGlobalFunctions` from [this answer][29], which expands all generically-defined (via patterns) global functions. The last example I want to include here (although it also is relevant for the third use case) is a macro for performing a code cleanup, discussed [here][30], and I particularly like the version by @WReach, which I will reproduce here:&#xD;
&#xD;
    SetAttributes[CleanUp, HoldAll]&#xD;
    CleanUp[expr_, cleanup_] :=&#xD;
      Module[{exprFn, result, abort = False, rethrow = True, seq}, &#xD;
        exprFn[] := expr;&#xD;
        result = &#xD;
          CheckAbort[&#xD;
             Catch[Catch[result = exprFn[]; rethrow = False; result], _, &#xD;
               seq[##] &amp;amp;], abort = True];&#xD;
        cleanup;&#xD;
        If[abort, Abort[]];&#xD;
        If[rethrow, Throw[result /. seq -&amp;gt; Sequence]];&#xD;
        result]&#xD;
&#xD;
It is not fully &amp;#034;bullet-proof&amp;#034;, but does a really good job in the majority of cases. &#xD;
&#xD;
###Examples of run-time code generation / new functionality&#xD;
&#xD;
Actually, many of the above examples also qualify here. I&amp;#039;ll add just one more here (in two variations): the abortable table from [this answer][31] (I will reproduce the final version here):&#xD;
&#xD;
&#xD;
    ClearAll[abortableTableAlt];&#xD;
    SetAttributes[abortableTableAlt, HoldAll];&#xD;
    abortableTableAlt[expr_, iter : {_Symbol, __} ..] :=&#xD;
      Module[{indices, indexedRes, sowTag, depth =  Length[Hold[iter]] - 1},&#xD;
       Hold[iter] /. {sym_Symbol, __} :&amp;gt; sym /. Hold[syms__] :&amp;gt; (indices := {syms});&#xD;
       indexedRes =  Replace[#, {x_} :&amp;gt; x] &amp;amp;@ Last@Reap[&#xD;
          CheckAbort[Do[Sow[{expr, indices}, sowTag], iter], Null],sowTag];&#xD;
       AbortProtect[&#xD;
          SplitBy[indexedRes, Array[Function[x, #[[2, x]] &amp;amp;], {depth}]][[##,1]] &amp;amp; @@ &#xD;
          Table[All, {depth + 1}]&#xD;
       ]];&#xD;
&#xD;
(it accepts the same syntax as `Table`, including the multidimensional case, but returns the partial list of accumulated results in the case of Abort[] -  see examples of use in the mentioned answer), and its version for a conditional `Table`, which only adds an element is certain condition is fulfilled - it is described [here][32].  There are of course many other examples in this category.&#xD;
&#xD;
###Examples of dynamic environments&#xD;
&#xD;
Dynamic environments can be very useful when you want to modify certain global variables or, which is much less trivial, functions, for a particular piece of code, so that the rest of the system remains unaffected. The typical constructs used to achieve this are `Block` and ``Internal`InheritedBlock``. &#xD;
&#xD;
The simplest and most familiar dynamic environment is obtained by changing the values of `$RecursionLimit` and / or `$IterationLimit` inside a `Block`. Some examples of use for these are in [my answer][33] in the discussion of tail call optimization in Mathematica. For a more complex example, see [my suggestion][34] for the recent question on convenient string manipulation. Some more examples can be found in my answer to [this question][35]. An example of application of this to profiling can be found [here][36]. &#xD;
&#xD;
Again, there are many more examples, many of which I probably missed here.&#xD;
&#xD;
###Problems with writing macros in Mathematica&#xD;
&#xD;
To my mind, the main problems with writing  and using macros consistently in Mathematica are these:&#xD;
&#xD;
 - Hard to control evaluation. No *real* quotation mechanism (`Hold` and `HoldComplete` don&amp;#039;t count because they create extra wrappers, and `Unevaluated` does not count since it is not permanent ans is stripped during the evaluation)&#xD;
 - Macros as described above are expanded from outside to inside. Coupled with the lack of *real* quotation mechanism, this leads to the absence of true macro composition out of the box. This composition can be achieved, but with some efforts&#xD;
 - The lack of the real compilation stage (The definition-time does not fully count since most definitions are delayed).&#xD;
&#xD;
To circumvent these issues, one has to apply various techniques, such as&#xD;
&#xD;
 -  [Trott - Strzebonski in-place evaluation technique][37] to evaluate parts of held expressions in-place (see also [this answer][38] for some more details on that)&#xD;
 -  A technique which I call (for the lack of a better name) &amp;#034;inverse rule-dressing&amp;#034;, which exploits the properties of delayed rule substitution (delayed, plus intrusive), to inject some unevaluated code. I used it in the first solution in [this answer][39], in more complex way in the `SavePointers` function in [this answer][40], and in a number of other cases. It has also been used very elegantly  in [this answer][41].&#xD;
 - using a custom `Hold`-like wrapper which is first mapped on (possibly all) parts of an expression, and later removed using rules. Two examples of this techniques are [here][42] and [here][43]&#xD;
 - ...&#xD;
&#xD;
Despite all these techniques being useful, and in total covering most of the needs for macro-writing, the need to use them (often in combinations) and the resulting code complexity shows, to my mind, the serious need for a generic library which would provide simpler means for macro-writing. I would prefer to be able to nest macros and not think about zillion of things that may go wrong because of some unwanted evaluation, but rather about things that really matter (such as variable captures).&#xD;
&#xD;
###Summary &#xD;
&#xD;
Macros are another very powerful meta-programming technique. While it *is* possible to write them in Mathematica, it is, as of now, a rather involved undertaking, and composing macros is an even harder task. Because composition in the key, I attribute the fact that macros are not in widespread use in Mathematica programming, to this lack of composition, plus the complexity of writing individual macros. That said, I think this is a very promising direction, and hope that some time soon we will have the tools which would make writing macros a more simple and automatic process.&#xD;
&#xD;
##DSL creation&#xD;
&#xD;
I won&amp;#039;t say almost anything here, except noting that this is entirely possible in Mathematica, and some nice syntax can be added easily via `UpValues`. &#xD;
&#xD;
##Final remarks&#xD;
&#xD;
I think that meta-programming is one of the most important and promising directions in the present and future of Mathematica programming. It is also rather complex, and IMO, largely unexplored in Mathematica still. I hope that this justifies this post being so long.&#xD;
&#xD;
I tried to summarize various approaches to meta-programming in Mathematica, which I am aware of, and give references to examples of these approaches, so that the reader can look for him/herself. Since meta-programming is a complex topic, I did not attempt to write a tutorial, but rather tried  to summarize various experiences of myself and others to produce a kind of a reference. &#xD;
&#xD;
One may notice that the references are dominated by the code I wrote. One reason for that is that I am a heavy user of meta-programming in Mathematica. Another reason is that everyone remembers own code the most. I have to apologize for not including some other references which did not come to my mind right away. I invite everyone to edit this post and add more references, which I missed. &#xD;
&#xD;
&#xD;
  [1]: https://mathematica.stackexchange.com/a/2352/81&#xD;
  [2]: http://community.wolfram.com/web/vitaliyk&#xD;
  [3]: https://stackoverflow.com/questions/4430998/mathematica-what-is-symbolic-programming/4435720#4435720&#xD;
  [4]: https://mathematica.stackexchange.com/questions/704/functions-vs-patterns/746#746&#xD;
  [5]: https://stackoverflow.com/questions/8867757/has-anyone-written-any-function-to-automatically-build-a-dependency-graph-of-an/8869545#8869545&#xD;
  [6]: https://mathematica.stackexchange.com/questions/36/file-backed-lists-variables-for-handling-large-data/209#209&#xD;
  [7]: https://stackoverflow.com/questions/6579644/savedefinitions-considered-dangerous/6580284#6580284&#xD;
  [8]: https://stackoverflow.com/questions/6451802/pattern-to-match-only-children-of-certain-elements/6453673#6453673&#xD;
  [9]: https://stackoverflow.com/questions/8700934/why-is-cases-so-slow-here-are-there-any-tricks-to-speed-it-up/8701756#8701756&#xD;
  [10]: https://gist.github.com/1683497&#xD;
  [11]: https://stackoverflow.com/questions/4787901/data-table-manipulation-in-mathematica/4788373#4788373&#xD;
  [12]: https://stackoverflow.com/questions/8240943/data-table-manipulation-in-mathematica-step-2&#xD;
  [13]: https://stackoverflow.com/questions/6130276/conditionnal-data-manipulation-in-mathematica&#xD;
  [14]: https://stackoverflow.com/questions/6236458/plot-using-with-versus-plot-using-block-mathematica/6236808#6236808&#xD;
  [15]: https://stackoverflow.com/questions/4973424/in-mathematica-how-do-i-compile-the-function-outer-for-an-arbitrary-number-of/4973603#4973603&#xD;
  [16]: https://stackoverflow.com/questions/8204784/how-to-compile-a-function-that-computes-the-hessian/8210224#8210224&#xD;
  [17]: https://stackoverflow.com/questions/4682742/optional-named-arguments-without-wrapping-them-all-in-optionvalue/4683924#4683924&#xD;
  [18]: https://mathematica.stackexchange.com/questions/1602/resource-management-in-mathematica/1603#1603&#xD;
  [19]: https://stackoverflow.com/questions/6560116/best-practices-in-error-reporting-mathematica/6563886#6563886&#xD;
  [20]: https://stackoverflow.com/questions/6214946/how-to-dynamically-generate-mathematica-code/6215394#6215394&#xD;
  [21]: https://stackoverflow.com/questions/8741671/unevaluated-form-of-ai/8742627#8742627&#xD;
  [22]: https://mathematica.stackexchange.com/questions/1315/customizing-syntax-highlighting-for-private-cell-styles/1320#1320&#xD;
  [23]: https://stackoverflow.com/questions/8741671/unevaluated-form-of-ai/8746584#8746584&#xD;
  [24]: https://stackoverflow.com/questions/4856177/preventing-evaluation-of-mathematica-expressions&#xD;
  [25]: https://stackoverflow.com/questions/1616592/mathematica-unevaluated-vs-defer-vs-hold-vs-holdform-vs-holdallcomplete-vs-etc&#xD;
  [26]: https://stackoverflow.com/questions/5866016/question-on-condition/5869885#5869885&#xD;
  [27]: https://mathematica.stackexchange.com/questions/36/file-backed-lists-variables-for-handling-large-data/209#209&#xD;
  [28]: https://stackoverflow.com/questions/8373526/error-generating-localized-variables-as-constants/8377522#8377522&#xD;
  [29]: https://mathematica.stackexchange.com/questions/704/functions-vs-patterns/746#746&#xD;
  [30]: https://stackoverflow.com/questions/3365794/reliable-clean-up-in-mathematica&#xD;
  [31]: https://stackoverflow.com/questions/6470625/mathematica-table-function/6471024#6471024&#xD;
  [32]: https://stackoverflow.com/questions/6367932/generate-a-list-in-mathematica-with-a-conditional-tested-for-each-element/6368770#6368770&#xD;
  [33]: https://stackoverflow.com/questions/4481301/tail-call-optimization-in-mathematica/4627671#4627671&#xD;
  [34]: https://mathematica.stackexchange.com/questions/344/convenient-string-manipulation/377#377&#xD;
  [35]: https://mathematica.stackexchange.com/questions/1162/alternative-to-overloading-set&#xD;
  [36]: https://mathematica.stackexchange.com/questions/1786/workbench-profile-question/1798#1798&#xD;
  [37]: http://library.wolfram.com/conferences/devconf99/villegas/UnevaluatedExpressions/Links/index_lnk_30.html&#xD;
  [38]: https://stackoverflow.com/questions/6633236/replace-inside-held-expression/6633334#6633334&#xD;
  [39]: https://stackoverflow.com/questions/6234701/how-to-block-symbols-without-evaluating-them/6236264#6236264&#xD;
  [40]: https://stackoverflow.com/questions/6579644/savedefinitions-considered-dangerous/6580284#6580284&#xD;
  [41]: https://mathematica.stackexchange.com/questions/1929/injecting-a-sequence-of-expressions-into-a-held-expression/1937#1937&#xD;
  [42]: https://stackoverflow.com/questions/5747742/uses-for-mapall/5749275#5749275&#xD;
  [43]: https://mathematica.stackexchange.com/questions/2137/truncate-treeform-to-show-only-the-top/2139#2139</description>
    <dc:creator>Leonid Shifrin</dc:creator>
    <dc:date>2017-06-16T12:08:12Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1250668">
    <title>[CALL] SpacePartition: design and applications</title>
    <link>https://community.wolfram.com/groups/-/m/t/1250668</link>
    <description>This is a call for some feedback on a small utility function I am trying to design. A few times I felt the need in a continuous partitioning of space. Could you please, after reading the post, give me some feedback on:&#xD;
&#xD;
- What other **applications** this function can be used for? (Especially higher-dimensional cases)&#xD;
- Do you have a better **design** suggestions?&#xD;
&#xD;
# Definition&#xD;
&#xD;
The SpacePartition function is a continuous analog of [Partition][1]. It subdivides n-dimensional space into integer number of partitions. The result is a tensor of hyper-blocks spanning the hyperspace without gaps or overlaps.  It means currently, and for simplicity of the demo, there are no block offsets, but they could be added in the future.&#xD;
&#xD;
    SpacePartition[space_List, partitions_List] :=&#xD;
      Outer[List, ##, 1] &amp;amp; @@ MapThread[Partition[Subdivide @@ Append[#1, #2], 2, 1] &amp;amp;, {space, partitions}]&#xD;
     &#xD;
#1D Examples&#xD;
&#xD;
Subdividing 1D interval {2.3,5.7} into 5 consecutive intervals:&#xD;
&#xD;
    part1D = SpacePartition[{{2.3, 5.7}}, {5}]&#xD;
&amp;gt; {{{2.3, 2.98}}, {{2.98, 3.66}}, {{3.66, 4.34}}, {{4.34, 5.02}}, {{5.02, 5.7}}}&#xD;
&#xD;
    NumberLinePlot[Interval @@@ part1D]&#xD;
&#xD;
![enter image description here][2]&#xD;
&#xD;
# 2D Examples &#xD;
&#xD;
Subdividing 2D rectangle into different number of partitions along different dimensions&#xD;
&#xD;
    part2D = SpacePartition[{{2.3, 5.7}, {1.2, 3.4}}, {7, 5}];&#xD;
&#xD;
and visualizing as a grid&#xD;
&#xD;
    Graphics[grid2D = {FaceForm[], EdgeForm[Black], Rectangle @@ Transpose[#]} &amp;amp; /@ &#xD;
    Flatten[part2D, 1], Frame -&amp;gt; True]&#xD;
&#xD;
![enter image description here][3]&#xD;
&#xD;
Subdivisions preserve the neighborhood structure &#xD;
&#xD;
    Graphics[{grid2D, {Opacity[.5], Rectangle @@ Transpose[#]} &amp;amp; /@ &#xD;
    (part2D[[##]] &amp;amp; @@@ Tuples[{1, 2, 3}, 2])}, Frame -&amp;gt; True]&#xD;
&#xD;
![enter image description here][4]&#xD;
&#xD;
# 3D Examples&#xD;
&#xD;
Subdividing 3D rectangle into different number of partitions along different dimensions&#xD;
&#xD;
    part3D = SpacePartition[{{2.3, 5.7}, {1.2, 3.4}, {-1.1, 2}}, {7, 5, 4}];&#xD;
&#xD;
and visualizing as a 3D grid&#xD;
&#xD;
    Graphics3D[{Opacity[.6], Cuboid @@ Transpose[#]} &amp;amp; /@ Flatten[part3D, 2], Axes -&amp;gt; True]&#xD;
&#xD;
![enter image description here][5]&#xD;
&#xD;
Selecting random subsets of subdivisions as Region:&#xD;
&#xD;
    Table[Show[Region[Cuboid @@ Transpose[#]] &amp;amp; /@ &#xD;
    RandomSample[Flatten[part3D, 2], 20], Axes -&amp;gt; True, Boxed -&amp;gt; True],3]&#xD;
&#xD;
![enter image description here][6]&#xD;
&#xD;
#  Application: quarterly temperatures or partitioning PlotRange&#xD;
&#xD;
Often data are so dense it is hard to distinguish details in a standard plot. &#xD;
&#xD;
    data = WeatherData[&amp;#034;KMDZ&amp;#034;, &amp;#034;Temperature&amp;#034;, {{2015}}];&#xD;
    plot = DateListPlot[data]&#xD;
&#xD;
![enter image description here][7]&#xD;
&#xD;
SpacePartition can be used to partition PlotRange and make a better visual&#xD;
&#xD;
    With[{pr = PlotRange /. Options[plot]},&#xD;
      DateListPlot[TimeSeriesWindow[data, #], AspectRatio -&amp;gt; 1/10, ImageSize -&amp;gt; 1000,&#xD;
         PlotRange -&amp;gt; {Automatic, {-30, 30}}, Filling -&amp;gt; Axis, PlotTheme -&amp;gt; &amp;#034;Detailed&amp;#034;] &amp;amp; /@&#xD;
          Map[DateList, Flatten[SpacePartition[{pr[[1]]}, {4}], 1], {2}]] // Column&#xD;
&#xD;
![enter image description here][8]&#xD;
&#xD;
#  Application: box-counting method for fractal measures&#xD;
&#xD;
Define an iterated function system (IFS) and iterate it on point sets&#xD;
&#xD;
    IFS[{T__TransformationFunction}][pl_List] := Join @@ Through[{T}[pl]]&#xD;
    IFSNest[f_IFS, pts_, n_Integer] := Nest[f, pts, n]&#xD;
&#xD;
Sierpi?ski gasket transformation:&#xD;
&#xD;
    SierpinskiGasket = With[{\[ScriptCapitalD] = DiagonalMatrix[{1, 1}/2]},&#xD;
       IFS[{AffineTransform[{\[ScriptCapitalD]}], &#xD;
         AffineTransform[{\[ScriptCapitalD], {1/2, 0}}], &#xD;
         AffineTransform[{\[ScriptCapitalD], {0.25, 0.433}}]}]];&#xD;
&#xD;
and corresponding iterated point set&#xD;
&#xD;
    ptsSierp = IFSNest[N@SierpinskiGasket, RandomReal[1, {100, 2}], 4];&#xD;
    graSierp = Graphics[{PointSize[Tiny], Point[ptsSierp]}, Frame -&amp;gt; True]&#xD;
&#xD;
![enter image description here][9]&#xD;
&#xD;
Function that makes partitions &#xD;
&#xD;
    blocks[n_]:=Rectangle@@Transpose[#]&amp;amp;/@Flatten[N@SpacePartition[{{0,1},{0,1}},{n,n}],1]&#xD;
    &#xD;
    Show[graSierp,Graphics[{FaceForm[],EdgeForm[Red],blocks[7]}]]&#xD;
&#xD;
![enter image description here][10]&#xD;
&#xD;
Of course number of partitions grows as a square for 2D case &#xD;
&#xD;
    Length /@ blocks /@ Range[9]&#xD;
&#xD;
&amp;gt; {1, 4, 9, 16, 25, 36, 49, 64, 81}&#xD;
&#xD;
Function counting partitions that have any points in them&#xD;
&#xD;
    blockCount[pts_, n_] := Length[Select[blocks[n], MemberQ[RegionMember[#, pts], True] &amp;amp;]]&#xD;
&#xD;
Accumulating data of partition count for different partition sizes &#xD;
&#xD;
    logMes = ParallelTable[Log@{k, blockCount[ptsSierp, k]}, {k, 20}];&#xD;
&#xD;
Fitting the log-log scale of the data linearly with the slope measuring fractal dimension  &#xD;
&#xD;
    fit[x] = Fit[logMes, {1, x}, x]&#xD;
&#xD;
&amp;gt; 0.0884774 + 1.70962 x&#xD;
&#xD;
which deviates a bit from ideal due to probably random inexact nature of IFS system&#xD;
&#xD;
    N[Log[3]/Log[2]]&#xD;
&#xD;
&amp;gt; 1.58496&#xD;
&#xD;
    Plot[fit[x], {x, 0, 3.5}, Epilog -&amp;gt; {Red, PointSize[.02], Point[logMes]}]&#xD;
&#xD;
![enter image description here][11]&#xD;
&#xD;
# Missing features&#xD;
&#xD;
The following features could be added in future:&#xD;
&#xD;
- Offset parameter for overlapping or gapped partitions&#xD;
&#xD;
- Real (non-integer) number of partitions&#xD;
&#xD;
&#xD;
  [1]: http://reference.wolfram.com/language/ref/Partition.html&#xD;
  [2]: http://community.wolfram.com//c/portal/getImageAttachment?filename=34q5wtreyhrgfeaw.png&amp;amp;userId=11733&#xD;
  [3]: http://community.wolfram.com//c/portal/getImageAttachment?filename=trtr54y5tr.png&amp;amp;userId=11733&#xD;
  [4]: http://community.wolfram.com//c/portal/getImageAttachment?filename=rtyjtey5764w3q.png&amp;amp;userId=11733&#xD;
  [5]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ehrfcxxvdasr5.png&amp;amp;userId=11733&#xD;
  [6]: http://community.wolfram.com//c/portal/getImageAttachment?filename=gsdfgdert5433.png&amp;amp;userId=11733&#xD;
  [7]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ldkr43t8vad.png&amp;amp;userId=11733&#xD;
  [8]: http://community.wolfram.com//c/portal/getImageAttachment?filename=45ytrwew4534yhrgfer.png&amp;amp;userId=11733&#xD;
  [9]: http://community.wolfram.com//c/portal/getImageAttachment?filename=jy5674w5tq3243.png&amp;amp;userId=11733&#xD;
  [10]: http://community.wolfram.com//c/portal/getImageAttachment?filename=534tyhtrer4t54thrgef.png&amp;amp;userId=11733&#xD;
  [11]: http://community.wolfram.com//c/portal/getImageAttachment?filename=34t4hwrge.png&amp;amp;userId=11733</description>
    <dc:creator>Vitaliy Kaurov</dc:creator>
    <dc:date>2017-12-20T00:36:24Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/935450">
    <title>How to implement hierarchical edge bundling in Mathematica?</title>
    <link>https://community.wolfram.com/groups/-/m/t/935450</link>
    <description>Hierarchical edge bundling is an interesting graph visualization technique that can make community structure evident in a network.  The D3 JavaScript library implements it and you can see a very nice interactive demo here: http://bl.ocks.org/mbostock/7607999&#xD;
&#xD;
![Hierarchical edge bundling](http://i.stack.imgur.com/mBqPa.png)&#xD;
&#xD;
How does it work?  Can Mathematica do this?  Can we implement this from scratch in Mathematica?&#xD;
&#xD;
I will show how to do this step by step below.  This is a repost of [an article I shared on Mathematica.SE yesterday][1], which in turn is based on a presentation I gave at the Wolfram seminars in Lyon and Grenoble on the preceding two days.  At the end you will find a small package that wraps everything up into an easy to use function.  But be warned: there is little to no error checking and it will be too slow for graphs bigger than a couple of hundred nodes.  There are probably better ways to implement some of the steps, so all feedback is welcome!&#xD;
&#xD;
----&#xD;
&#xD;
Before we get started, I want to note that it turns out that Mathematica does include an implementation of this layout.  It can be used like this:  &#xD;
&#xD;
    SetProperty[ExampleData[{&amp;#034;NetworkGraph&amp;#034;, &amp;#034;DolphinSocialNetwork&amp;#034;}], &#xD;
     GraphLayout -&amp;gt; {&amp;#034;EdgeLayout&amp;#034; -&amp;gt; &amp;#034;HierarchicalEdgeBundling&amp;#034;}]&#xD;
&#xD;
![HEB in Mma](http://i.stack.imgur.com/rxh6U.png)&#xD;
&#xD;
This is not exactly the usual syntax for the `GraphLayout` option, and is not clearly described in the documentation (it really should be for such a cool visualization!!), so I though it&amp;#039;s good to share it.  More info here: http://mathematica.stackexchange.com/a/127995/12&#xD;
&#xD;
It is still interesting to implement the layout on our own.  Not only can we learn about the method, we will also gain the flexibility to tweak it and gain completely different interesting outputs, e.g. a linear node arrangement instead of a circular one.&#xD;
&#xD;
----&#xD;
&#xD;
Below I am going to show how to implement hierarchical edge bundling from scratch.  I hope that people will find this useful both from an educational point of view and to be able to customize the layout to their taste.&#xD;
&#xD;
On the way we are going to get a little help from [the IGraph/M package][2], the [igraph][3] interface for Mathematica.  IGraph/M was in turn made possible by the [LTemplate](http://community.wolfram.com/groups/-/m/t/575100).&#xD;
&#xD;
## How does the layout work?&#xD;
&#xD;
This type of layout is useful because it makes the community structure in the graph evident.  It is based on [hierarchical community detection][4].  A detailed description can be found in [Y Jia, M Garland, JC Hart: Hierarchial edge bundles for general graphs](http://graphics.cs.illinois.edu/sites/default/files/edgebundles.pdf).  I will admit that I didn&amp;#039;t actually read this paper.  I only looked at the figures for inspiration.  After all I am doing this for fun, not for a perfect result.  However, if you want to get deeper into the topic, it is probably a good idea to read it.&#xD;
&#xD;
The first reason why we need IGraph/M is that we are going to need to use a dendrogram output by some hierarchical community detection algorithm.  IGraph/M has several such functions:&#xD;
&#xD;
    &amp;lt;&amp;lt;IGraphM`&#xD;
&#xD;
[![enter image description here][5]][5]&#xD;
&#xD;
All these functions return an `IGClusterData` object.  We can then query several `&amp;#034;Properties&amp;#034;` of such an object.&#xD;
&#xD;
As an example, let us analyse the following network:&#xD;
&#xD;
    g = ExampleData[{&amp;#034;NetworkGraph&amp;#034;, &amp;#034;DolphinSocialNetwork&amp;#034;}]&#xD;
&#xD;
[![enter image description here][6]][6]&#xD;
&#xD;
This is a social network between dolphins.  Like most social networks, it has a relatively clear community structure.&#xD;
&#xD;
    cl = IGCommunitiesEdgeBetweenness[g]&#xD;
&#xD;
[![enter image description here][7]][7]&#xD;
&#xD;
Running the edge betweenness based (Girvan-Newman) community detection algorithm on it yields 5 communities.  Note that we could also get this using the builtin `FindGraphCommunities[..., Method -&amp;gt; &amp;#034;Centrality&amp;#034;]`, however, this function doesn&amp;#039;t give us the full dendrogram.&#xD;
&#xD;
Notice in the above screenshot of the `IGClusterData` object that it says: &amp;#034;Hierarchical: True&amp;#034;.  Not all algorithms included in igraph will produce a hierarchical structure, but this one does.  We can visualize the dendrogram like this:&#xD;
&#xD;
    &amp;lt;&amp;lt; HierarchicalClustering`&#xD;
    DendrogramPlot[cl[&amp;#034;HierarchicalClusters&amp;#034;], LeafLabels -&amp;gt; (Rotate[#, Pi/2] &amp;amp;)]&#xD;
&#xD;
[![enter image description here][8]][8]&#xD;
&#xD;
&amp;lt;sup&amp;gt;Note: In IGraph/M 0.3.0 (not released as of this writing), it will be possible to plot the dendrogram using `Dendrogram[cl[&amp;#034;Tree&amp;#034;]]`.  [`Dendrogram`](http://reference.wolfram.com/language/ref/Dendrogram.html) is new in M10.4.&amp;lt;/sup&amp;gt;&#xD;
&#xD;
Other clustering algorithms in IGraph/M that can produce a dendrogram are Walktrap and Greedy, both being faster than EdgeBetweenness.&#xD;
&#xD;
We can also obtain this dendrogram as a clustering tree, i.e. a `Graph` object.&#xD;
&#xD;
    tree = cl[&amp;#034;Tree&amp;#034;]&#xD;
&#xD;
[![enter image description here][9]][9]&#xD;
&#xD;
**So how does hierarchical edge bundling work?** Instead of layout out the graph `g`, it constructs a version of the clustering tree and lays it out radially.  The leaves correspond to the nodes of the original graph `g`.  Then it uses this tree as a skeleton to route the edges of `g` between its nodes.  The following figure from the paper gives an reasonably clear idea:&#xD;
&#xD;
[![enter image description here][10]][10]&#xD;
&#xD;
Let&amp;#039;s go ahead then an implement this in Mathematica.&#xD;
&#xD;
## Implementing the layout&#xD;
&#xD;
As a first step, we must simplify the clustering tree by identifying the subtrees corresponding to each cluster, and collapsing them into a single node, with all members of the community connecting directly to it.&#xD;
&#xD;
Using a radial visualization of the tree, the graph on the left is what the algorithm gave us, and the one on the right is what we can use as a practical skeleton:&#xD;
&#xD;
[![enter image description here][11]][11]&#xD;
&#xD;
First of all, we must identify the root of the tree.  Since this is a *binary tree*, we can just take the single node with degree 2.  Leaves will have degree 1 and intermediate nodes will have degree 3. &#xD;
&#xD;
    root = First@Pick[VertexList[tree], VertexDegree[tree], 2]&#xD;
    (* 123 *)&#xD;
&#xD;
Let us also get rid of the vertex labels and put back the nodes into the visualization, so we can see better what we are doing:&#xD;
&#xD;
    tree = SetProperty[RemoveProperty[tree, VertexLabels], &#xD;
      VertexShapeFunction -&amp;gt; &amp;#034;Circle&amp;#034;]&#xD;
&#xD;
[![enter image description here][12]][12]&#xD;
&#xD;
The clustering tree has integers as its nodes. We are going to need to forward and reverse mapping between the leaves of this tree and the graph g.&#xD;
&#xD;
    map = AssociationThread[Range@VertexCount[g], VertexList[g]];&#xD;
    revmap = Association[Reverse /@ Normal[map]];&#xD;
&#xD;
&amp;lt;sup&amp;gt;Note: In IGraph/M 0.3.0 (not released as of this writing) it will be possible to simply use `map = PropertyValue[tree, &amp;#034;LeafLabels&amp;#034;];`&amp;lt;/sup&amp;gt;&#xD;
&#xD;
Now we group the leaves of the clustering tree based on which community they belong to. Note the use of Lookup and Map instead of ReplaceAll to prevent unpredictable replacements, especially in cases when some graph nodes are lists themselves.&#xD;
&#xD;
    communities = Lookup[revmap, #] &amp;amp; /@ cl[&amp;#034;Communities&amp;#034;]&#xD;
    (* {{1, 3, 11, 29, 31, 43, 48}, &#xD;
        {2, 6, 7, 8, 10, 14, 18, 20, 23, 26, 27, 28, 32, 33, 40, 42, 49, 55, 57, 58, 61}, &#xD;
        {4, 9, 13, 15, 17, 21, 34, 35, 37, 38, 39, 41, 44, 45, 47, 50, 51, 53, 59, 60}, {5, 12, 16, 19, 22, 24, 25, 30, 36, 46, 52, 56}, &#xD;
        {54, 62}} *)&#xD;
&#xD;
To extract the subtree of a community, we make use of the fact that in an (undirected) tree there is precisely one path between any two nodes. Mapping enough paths to connect any two leaves will give us the subtree.&#xD;
&#xD;
    Clear[subtree]&#xD;
    subtree[tree_, {el_}] := {el}&#xD;
    subtree[tree_, community_] := &#xD;
     Union @@ (First@FindPath[UndirectedGraph[tree], ##] &amp;amp;) @@@ Partition[community, 2, 1]&#xD;
&#xD;
    HighlightGraph[tree, subtree[tree, #] &amp;amp; /@ communities, &#xD;
     GraphHighlightStyle -&amp;gt; &amp;#034;DehighlightFade&amp;#034;]&#xD;
&#xD;
[![enter image description here][13]][13]&#xD;
&#xD;
    The root of a subtree is the node that appears first in the breadth-first ordering. Alternatively we could look for the only degree-2 node in the subtree, but let&amp;#039;s use BFS here.  We can create is using [`BreadthFirtScan`](http://reference.wolfram.com/language/ref/BreadthFirtScan.html).&#xD;
&#xD;
    ord = First@Last@Reap[&#xD;
             BreadthFirstScan[tree, root, {&amp;#034;PrevisitVertex&amp;#034; -&amp;gt; Sow}];&#xD;
          ];&#xD;
&#xD;
For those not familiar with what breadth-first ordering is, the following animation will be educational. Nodes are visited in the order of their distance from the starting pointin this case from the tree root.&#xD;
&#xD;
    Animate[&#xD;
     HighlightGraph[&#xD;
      SetProperty[RemoveProperty[tree, VertexLabels], VertexShapeFunction -&amp;gt; &amp;#034;Circle&amp;#034;],&#xD;
      Take[ord, k]&#xD;
      ],&#xD;
     {k, 1, VertexCount[tree], 1}&#xD;
     ]&#xD;
&#xD;
[![enter image description here][14]][14]&#xD;
&#xD;
So let&amp;#039;s get the roots of the subtrees:&#xD;
&#xD;
    posIndex = First /@ PositionIndex[ord];&#xD;
    subtreeRoots = First@MinimalBy[subtree[tree, #], posIndex] &amp;amp; /@ communities&#xD;
    (* {101, 119, 118, 112, 63} *)&#xD;
    &#xD;
    HighlightGraph[tree, subtreeRoots, GraphHighlightStyle -&amp;gt; &amp;#034;Thick&amp;#034;]&#xD;
&#xD;
[![enter image description here][15]][15]&#xD;
&#xD;
New let&amp;#039;s extract the tree which has these vertices as its leaves:&#xD;
&#xD;
    rootTree = &#xD;
     Subgraph[tree, VertexInComponent[tree, subtreeRoots], &#xD;
      GraphLayout -&amp;gt; &amp;#034;LayeredDigraphEmbedding&amp;#034;]&#xD;
&#xD;
[![enter image description here][16]][16]&#xD;
&#xD;
Notice that this is not going to make a useful skeleton because the different leaves have different distances from the root.  Let us augment it with intermediate nodes to force all leaves to the same distance.  A better method would not modify the treeit would modify how the tree is embedded in space instead.  But I am lazy so I will just do the augmentation here.  I will use the symbolic wrapper `a` to generate names for the new nodes.&#xD;
&#xD;
    (* renaming the community roots will make things easier for cases where we have single-node communities *)&#xD;
    rootTree = VertexReplace[rootTree, Thread[subtreeRoots -&amp;gt; (a[#][0]&amp;amp;) /@ subtreeRoots]];&#xD;
    subtreeRoots = (a[#][0]&amp;amp;) /@ subtreeRoots;&#xD;
&#xD;
    dist = AssociationMap[GraphDistance[rootTree, root, #] &amp;amp;, subtreeRoots];&#xD;
    maxd = Max[dist];    &#xD;
&#xD;
    augmentedRootTree =&#xD;
     Graph[&#xD;
      GraphUnion[&#xD;
       rootTree,&#xD;
       GraphUnion @@ Table[&#xD;
         PathGraph[&#xD;
          Prepend[Head[node] /@ Range[maxd - dist[node]], node],&#xD;
          DirectedEdges -&amp;gt; True&#xD;
          ],&#xD;
         {node, subtreeRoots}&#xD;
         ]&#xD;
       ],&#xD;
      GraphLayout -&amp;gt; &amp;#034;LayeredDigraphEmbedding&amp;#034;&#xD;
      ]&#xD;
&#xD;
[![enter image description here][17]][17]&#xD;
&#xD;
This is what we need.  Now we just need to &amp;#034;hang&amp;#034; all nodes of `g` on the leaves of this tree.  Let&amp;#039;s extract the leaves in the same order as the communities:&#xD;
&#xD;
    rootTreeLeaves = &#xD;
      MapThread[Head[#1][#2] &amp;amp;, {subtreeRoots, Values[maxd - dist]}];&#xD;
    &#xD;
    augmentedTree = SetProperty[&#xD;
      GraphUnion[&#xD;
       augmentedRootTree,&#xD;
       GraphUnion @@ MapThread[Thread[#1 -&amp;gt; #2] &amp;amp;, {rootTreeLeaves, communities}]&#xD;
       ],&#xD;
      GraphLayout -&amp;gt; {&amp;#034;RadialDrawing&amp;#034;, &amp;#034;RootVertex&amp;#034; -&amp;gt; root}&#xD;
      ]&#xD;
&#xD;
[![enter image description here][18]][18]&#xD;
&#xD;
This is the tree we can use as a skeleton.  But if we use the built-in radial tree visualization, then the leaves are not equispaced on a circle.  Thus we employ the help of IGraph/M again and use its implementation of the Reingold-Tilford algorithm:&#xD;
&#xD;
    skeleton = IGLayoutReingoldTilfordCircular[augmentedTree, &#xD;
     &amp;#034;RootVertices&amp;#034; -&amp;gt; {root}]&#xD;
&#xD;
[![enter image description here][19]][19]&#xD;
&#xD;
We want to route the edges of `g` guided by the paths between them in the clustering tree, e.g.&#xD;
&#xD;
    spf = FindShortestPath[UndirectedGraph@augmentedTree, All, All];&#xD;
    HighlightGraph[&#xD;
     IGLayoutReingoldTilfordCircular[UndirectedGraph[augmentedTree], &#xD;
      &amp;#034;RootVertices&amp;#034; -&amp;gt; {root}],&#xD;
     Part[PathGraph /@ spf @@@ Map[revmap, EdgeList[g], {2}], 9],&#xD;
     GraphHighlightStyle -&amp;gt; &amp;#034;Thick&amp;#034;]&#xD;
&#xD;
[![enter image description here][20]][20]&#xD;
&#xD;
One simple way to do this is to use a `BSplineCurve`, with the intermediate points in the clustering tree as control points.  But this will result in a very tight bundling of edges.  To counter this, we can create new control points by interpolating between the original ones and a straight line going through the end vertices.  The following function will do this:&#xD;
&#xD;
    Clear[smoothen]&#xD;
    smoothen[curve_, v_] :=     &#xD;
     Module[{s = First[curve], t = Last[curve], line},&#xD;
      line = Table[s + (t - s) u, {u, 0, 1, 1/(Length[curve] - 1)}];&#xD;
      v line + (1 - v) curve&#xD;
     ]&#xD;
&#xD;
This function constructs the B splines:&#xD;
&#xD;
    Clear[plotGraph]&#xD;
    plotGraph[augmentedTree_, g_, v_: 0, sz_: 0.02] :=     &#xD;
     Module[{pts, paths, spf},&#xD;
      spf = FindShortestPath[UndirectedGraph@augmentedTree, All, All];&#xD;
      pts = GraphEmbedding[augmentedTree];&#xD;
      paths = spf @@@ Map[revmap, EdgeList[g], {2}];&#xD;
      Graphics[&#xD;
       {&#xD;
        {&#xD;
         Opacity[0.5], ColorData[&amp;#034;Legacy&amp;#034;][&amp;#034;RoyalBlue&amp;#034;],&#xD;
         Table[&#xD;
          With[&#xD;
           {curve = &#xD;
             PropertyValue[{augmentedTree, #}, VertexCoordinates] &amp;amp; /@ &#xD;
              path},&#xD;
           BSplineCurve[smoothen[curve, v], &#xD;
            SplineDegree -&amp;gt; Length[curve] - 1]&#xD;
           ],&#xD;
          {path, paths}&#xD;
          ]&#xD;
         },&#xD;
        {&#xD;
         PointSize[sz], Black,&#xD;
         Point[PropertyValue[{augmentedTree, #}, VertexCoordinates]] &amp;amp; /@ &#xD;
          Range@VertexCount[g]&#xD;
         }&#xD;
        }&#xD;
       ]&#xD;
      ]&#xD;
&#xD;
Now let&amp;#039;s take our skeleton and apply the visualization:&#xD;
&#xD;
    plotGraph[skeleton, g, 0.1]&#xD;
&#xD;
[![enter image description here][21]][21]&#xD;
&#xD;
It&amp;#039;s interesting to use a `Manipulate` to control the tightness of the edge bundling:&#xD;
&#xD;
    Manipulate[plotGraph[skeleton, g, v], {v, 0, 1}]&#xD;
&#xD;
[![enter image description here][22]][22]&#xD;
&#xD;
Now with everything in place, we can try to use other skeletons as well.  Using a standard top-to-bottom tree visualization the vertices are placed on a line:&#xD;
&#xD;
    skeleton = SetProperty[augmentedTree, GraphLayout -&amp;gt; &amp;#034;LayeredDigraphEmbedding&amp;#034;];&#xD;
    Show[&#xD;
     plotGraph[skeleton, g, 0.2, 0.01],&#xD;
     AspectRatio -&amp;gt; 1/3&#xD;
     ]&#xD;
&#xD;
[![enter image description here][23]][23]&#xD;
&#xD;
How about a KamadaKawai type layout for the tree?&#xD;
&#xD;
    skeleton = IGLayoutKamadaKawai[augmentedTree];&#xD;
    plotGraph[skeleton, g, 0.1]&#xD;
&#xD;
[![enter image description here][24]][24]&#xD;
&#xD;
With a bit more work we can also make this dynamic with clickable vertex labels, like in the example at http://bl.ocks.org/mbostock/7607999  The code is after the break.&#xD;
&#xD;
[![enter image description here][25]][25]&#xD;
&#xD;
I hope you enjoyed this little demo.  I apologize for the messy code and for not packaging this up into a single function.  I might do that on a better day when I have more time.  Any feedback is welcome.&#xD;
&#xD;
----&#xD;
&#xD;
## Code for Dynamic version&#xD;
&#xD;
    v = 0.15;&#xD;
    paths = spf @@@ Map[revmap, EdgeList[g], {2}];&#xD;
    With[{augmentedTree = &#xD;
       IGLayoutReingoldTilfordCircular[augmentedTree, &#xD;
        &amp;#034;RootVertices&amp;#034; -&amp;gt; {root}]}, &#xD;
     DynamicModule[{flags = &#xD;
        AssociationThread[Range@VertexCount[g], &#xD;
         ConstantArray[False, VertexCount[g]]]},&#xD;
      Graphics[&#xD;
       {&#xD;
        {&#xD;
         Opacity[0.5], ColorData[&amp;#034;Legacy&amp;#034;][&amp;#034;RoyalBlue&amp;#034;],&#xD;
         Table[&#xD;
          With[{curve = &#xD;
             PropertyValue[{augmentedTree, #}, VertexCoordinates] &amp;amp; /@ &#xD;
              path},&#xD;
           BSplineCurve[smoothen[curve, v], &#xD;
            SplineDegree -&amp;gt; Length[curve] - 1]&#xD;
           ],&#xD;
          {path, paths}&#xD;
          ],&#xD;
         Table[&#xD;
          With[{curve = &#xD;
             PropertyValue[{augmentedTree, #}, VertexCoordinates] &amp;amp; /@ &#xD;
              path, f = First[path], l = Last[path]},&#xD;
           Dynamic@&#xD;
              Style[#, &#xD;
               If[flags[f] || flags[l], &#xD;
                Directive[Thickness[0.007], Red, Opacity[1]], &#xD;
                Opacity[0]]] &amp;amp;@&#xD;
            BSplineCurve[smoothen[curve, v], &#xD;
             SplineDegree -&amp;gt; Length[curve] - 1]&#xD;
           ],&#xD;
          {path, paths}&#xD;
          ]&#xD;
         },&#xD;
        {&#xD;
         PointSize[0.02],&#xD;
         With[{pt = PropertyValue[{augmentedTree, #}, VertexCoordinates], &#xD;
             offset = 1.05},&#xD;
            EventHandler[&#xD;
             {Dynamic[If[flags[#], Red, Black]],&#xD;
              &#xD;
              Rotate[Text[VertexList[g][[#]], &#xD;
                offset pt, {-Sign@First[pt], 0}], &#xD;
               If[First[pt] &amp;lt; 0, Pi, 0] + ArcTan @@ pt, offset pt],&#xD;
              Point[pt]&#xD;
              },&#xD;
             {&amp;#034;MouseClicked&amp;#034; :&amp;gt; (flags[#] = ! flags[#])}&#xD;
             ]&#xD;
            ] &amp;amp; /@ Range@VertexCount[g]&#xD;
         }&#xD;
        },&#xD;
       ImageSize -&amp;gt; Large&#xD;
       ]&#xD;
      ]&#xD;
     ]&#xD;
&#xD;
----&#xD;
&#xD;
## Package&#xD;
&#xD;
This is a small package containing the above functionality.  To get started, simply apply HEBPlot to a *connected* graph which is not too large. Check `Options[HEBPlot]` for more control over the output.  Warning: This is a rudimentary package with limited options and very little error checking.&#xD;
&#xD;
Example:&#xD;
&#xD;
    HEBPlot[ExampleData[{&amp;#034;NetworkGraph&amp;#034;, &amp;#034;JazzMusicians&amp;#034;}],&#xD;
     &amp;#034;CommunityDetectionFunction&amp;#034; -&amp;gt; IGCommunitiesGreedy, &#xD;
     EdgeStyle -&amp;gt; Directive[Opacity[0.2], RGBColor[0.254906, 0.411802, 0.882397]],&#xD;
     VertexSize -&amp;gt; 0.01]&#xD;
&#xD;
[![enter image description here][26]][26]&#xD;
&#xD;
    BeginPackage[&amp;#034;HierarchicalEdgeBundling`&amp;#034;, {&amp;#034;IGraphM`&amp;#034;}];&#xD;
    &#xD;
    HEBSkeleton::usage = &amp;#034;HEBSkeleton[clusterData] constructs a skeleton usable for hierarhical edge bundling. The argument must be an IGClusterData object.&amp;#034;;&#xD;
    HEBEmbedSkeleton::usage = &amp;#034;HEBEmbedSkeleton[tree, layout] lays out a skeleton tree using \&amp;#034;Circular\&amp;#034; or \&amp;#034;Linear\&amp;#034; layouts.&amp;#034;;&#xD;
    HEBLayout::usage = &amp;#034;HEBLayout[graph, tree] visualizes graph based on a precomputed skeleton tree.&amp;#034;;&#xD;
    HEBPlot::usage = &amp;#034;HEBPlot[graph] visualizes graph using hierarchical edge bundling.&amp;#034;;&#xD;
    &#xD;
    Begin[&amp;#034;`Private`&amp;#034;];&#xD;
    &#xD;
    a; (* symbol for naming vertices augmenting the skeleton tree *)&#xD;
    &#xD;
    subtree[tree_, {el_}] := {el}&#xD;
    subtree[tree_, community_?ListQ] := &#xD;
    	Union @@ (First@FindPath[UndirectedGraph[tree], ##]&amp;amp;) @@@ Partition[community, 2, 1]&#xD;
    &#xD;
    HEBSkeleton::nohr = &amp;#034;The cluster data does not contain hierarchical information.&amp;#034;;&#xD;
    &#xD;
    HEBSkeleton[cl_IGClusterData] :=&#xD;
    	Module[{tree, root, ord, revmap, communities, posIndex, subtreeRoots, rootTree, dist, maxd, augmentedRootTree, rootTreeLeaves},&#xD;
    	  If[Not@MemberQ[cl[&amp;#034;Properties&amp;#034;], &amp;#034;Merges&amp;#034;],&#xD;
    	    Return@Failure[&amp;#034;NotHierarchical&amp;#034;, &amp;lt;|&amp;#034;MessageTemplate&amp;#034; -&amp;gt; HEBSkeleton::nohr|&amp;gt;]&#xD;
    	  ];&#xD;
    	  tree = cl[&amp;#034;Tree&amp;#034;];&#xD;
    	  root = First@Pick[VertexList[tree], VertexDegree[tree], 2];&#xD;
    	  ord = First@Last@Reap[BreadthFirstScan[tree, root, {&amp;#034;PrevisitVertex&amp;#034;-&amp;gt;Sow}];];&#xD;
    	  revmap = AssociationThread[cl[&amp;#034;Elements&amp;#034;], Range@cl[&amp;#034;ElementCount&amp;#034;]];&#xD;
    	  communities = Lookup[revmap, #]&amp;amp; /@ cl[&amp;#034;Communities&amp;#034;];&#xD;
    	  posIndex = First /@ PositionIndex[ord];&#xD;
          subtreeRoots = First@MinimalBy[subtree[tree,#], posIndex]&amp;amp; /@ communities;&#xD;
          rootTree = Subgraph[tree, VertexInComponent[tree, subtreeRoots]];&#xD;
          rootTree = VertexReplace[rootTree, Thread[subtreeRoots -&amp;gt; (a[#][0]&amp;amp;) /@ subtreeRoots]];&#xD;
          subtreeRoots = (a[#][0]&amp;amp;) /@ subtreeRoots;&#xD;
          dist = AssociationMap[GraphDistance[rootTree, root, #]&amp;amp;, subtreeRoots];&#xD;
    	  maxd = Max[dist];&#xD;
    	  augmentedRootTree = Graph[&#xD;
    	    GraphUnion[&#xD;
    	      rootTree,&#xD;
    	      GraphUnion @@ Table[&#xD;
    	        PathGraph[&#xD;
    	          Prepend[Head[node] /@ Range[maxd-dist[node]], node],&#xD;
    	          DirectedEdges-&amp;gt;True&#xD;
    	        ],&#xD;
    	        {node, subtreeRoots}&#xD;
    	      ]&#xD;
    	    ]&#xD;
    	  ];&#xD;
    	  rootTreeLeaves = MapThread[Head[#1][#2]&amp;amp;, {subtreeRoots, Values[maxd-dist]}];&#xD;
    	  GraphUnion[&#xD;
    	    augmentedRootTree,&#xD;
    	    GraphUnion@@MapThread[Thread[#1-&amp;gt;#2]&amp;amp;, {rootTreeLeaves,communities}]&#xD;
    	  ]&#xD;
    	]&#xD;
    	&#xD;
    HEBEmbedSkeleton[tree_?TreeGraphQ, layout_String : &amp;#034;Circular&amp;#034;] :=&#xD;
    	Switch[layout,&#xD;
    		&amp;#034;Circular&amp;#034;, IGLayoutReingoldTilfordCircular[tree, &amp;#034;RootVertices&amp;#034; -&amp;gt; Pick[VertexList[tree], VertexInDegree[tree], 0]],&#xD;
    		&amp;#034;Linear&amp;#034;, SetProperty[tree, GraphLayout -&amp;gt; &amp;#034;LayeredDigraphEmbedding&amp;#034;]&#xD;
    	]&#xD;
    &#xD;
    smoothen[curve_,v_]:=&#xD;
    	Module[{s = First[curve], t = Last[curve], line},&#xD;
    	  line = Table[s+(t-s)u,{u,0,1,1/(Length[curve]-1)}];&#xD;
    	  v line+(1-v) curve&#xD;
    	]&#xD;
    &#xD;
    Options[HEBLayout] = {&#xD;
    	&amp;#034;BundleTightness&amp;#034; -&amp;gt; 0.1, &#xD;
    	VertexSize -&amp;gt; 0.02, &#xD;
    	VertexStyle -&amp;gt; Black, &#xD;
    	EdgeStyle -&amp;gt; Directive[Opacity[0.5], ColorData[&amp;#034;Legacy&amp;#034;][&amp;#034;RoyalBlue&amp;#034;]]&#xD;
    };&#xD;
    &#xD;
    HEBLayout[g_?GraphQ, tree_?TreeGraphQ, opt : OptionsPattern[]] := &#xD;
    	Module[{paths, spf, v = OptionValue[&amp;#034;BundleTightness&amp;#034;], revmap},&#xD;
    		spf = FindShortestPath[UndirectedGraph[tree], All, All];&#xD;
    		revmap = AssociationThread[VertexList[g], Range@VertexCount[g]];&#xD;
    		paths = spf@@@Map[revmap, EdgeList[g], {2}];&#xD;
    		Graphics[&#xD;
    			{&#xD;
    				{&#xD;
    					OptionValue[EdgeStyle],&#xD;
    					Table[&#xD;
    						With[&#xD;
    							{curve=PropertyValue[{tree, #}, VertexCoordinates]&amp;amp;/@path},&#xD;
    							 BSplineCurve[smoothen[curve,v], SplineDegree -&amp;gt; Length[curve]-1]&#xD;
    						],&#xD;
    						{path,paths}&#xD;
    					]&#xD;
    				},&#xD;
    				{&#xD;
    					PointSize@OptionValue[VertexSize], OptionValue[VertexStyle],&#xD;
    					Point[PropertyValue[{tree, #},VertexCoordinates]]&amp;amp;/@Range@VertexCount[g]&#xD;
    				}&#xD;
    			}&#xD;
    		]&#xD;
    	]&#xD;
    	&#xD;
    Options[HEBPlot] = Options[HEBLayout] ~Join~ {&amp;#034;Layout&amp;#034; -&amp;gt; &amp;#034;Circular&amp;#034;, &amp;#034;CommunityDetectionFunction&amp;#034; -&amp;gt; IGCommunitiesEdgeBetweenness};&#xD;
    &#xD;
    HEBPlot[g_?ConnectedGraphQ, opt : OptionsPattern[]] :=&#xD;
    	Module[{cl, skeleton},&#xD;
    	  cl = OptionValue[&amp;#034;CommunityDetectionFunction&amp;#034;][g];&#xD;
    	  skeleton = HEBSkeleton[cl];&#xD;
    	  skeleton = HEBEmbedSkeleton[skeleton, OptionValue[&amp;#034;Layout&amp;#034;]];&#xD;
    	  HEBLayout[g, skeleton, FilterRules[{opt}, Keys@Options[HEBLayout]]]&#xD;
    	]&#xD;
    &#xD;
    End[];&#xD;
    &#xD;
    EndPackage[];&#xD;
&#xD;
&#xD;
  [1]: http://mathematica.stackexchange.com/q/55367/12&#xD;
  [2]: https://github.com/szhorvat/IGraphM&#xD;
  [3]: http://igraph.org/&#xD;
  [4]: https://en.wikipedia.org/wiki/Community_structure&#xD;
  [5]: http://i.stack.imgur.com/vdM9C.png&#xD;
  [6]: http://i.stack.imgur.com/rwRWH.png&#xD;
  [7]: http://i.stack.imgur.com/WcEXQ.png&#xD;
  [8]: http://i.stack.imgur.com/kmZx9.png&#xD;
  [9]: http://i.stack.imgur.com/2PyDH.png&#xD;
  [10]: http://i.stack.imgur.com/Qb28C.png&#xD;
  [11]: http://i.stack.imgur.com/ywHw8.png&#xD;
  [12]: http://i.stack.imgur.com/CdcZS.png&#xD;
  [13]: http://i.stack.imgur.com/CcB1g.png&#xD;
  [14]: http://i.stack.imgur.com/SBfFK.gif&#xD;
  [15]: http://i.stack.imgur.com/6IbzH.png&#xD;
  [16]: http://i.stack.imgur.com/IhqWp.png&#xD;
  [17]: http://i.stack.imgur.com/KIOAn.png&#xD;
  [18]: http://i.stack.imgur.com/x4h7N.png&#xD;
  [19]: http://i.stack.imgur.com/ZPlaw.png&#xD;
  [20]: http://i.stack.imgur.com/yBWMi.png&#xD;
  [21]: http://i.stack.imgur.com/5Gyn7.png&#xD;
  [22]: http://i.stack.imgur.com/hC5Ng.gif&#xD;
  [23]: http://i.stack.imgur.com/5GbSe.png&#xD;
  [24]: http://i.stack.imgur.com/h4SHo.png&#xD;
  [25]: http://i.stack.imgur.com/yzhYK.png&#xD;
  [26]: http://i.stack.imgur.com/e9v8k.png</description>
    <dc:creator>Szabolcs Horvát</dc:creator>
    <dc:date>2016-10-06T19:52:24Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/550504">
    <title>Who can fix math education, and how? Your thoughts please...</title>
    <link>https://community.wolfram.com/groups/-/m/t/550504</link>
    <description>![Look familiar...?][1]&#xD;
&#xD;
When last did you solve a quadratic equation by hand? Probably not since school, I&amp;#039;m guessing. It&amp;#039;s an open secret that maths education is way behind the times, failing to equip kids with skills they need in the real world. &#xD;
&#xD;
As a Wolfram Community member, you may well have come across the [Computer-Based Maths initiative][2], driven by Conrad Wolfram. For those who don&amp;#039;t know, it&amp;#039;s a programme designed to bring coding and computers into school maths curricula worldwide, using Wolfram technology. &#xD;
&#xD;
And now the CBM team wants *your* ideas ahead of the fourth [CBM Summit in London on 19-20 November][3]. We already have Jaak Aaviksoo, Simon Peyton Jones and Raspberry Pi&amp;#039;s Eben Upton, who [spoke at the last CBM Summit][4] in 2013. Now we&amp;#039;d like to hear from you...&#xD;
&#xD;
- Who would *you* like to hear speaking on this subject? &#xD;
- Do you have something you&amp;#039;d like to present yourself? &#xD;
- What are the most important topics that should be covered?&#xD;
&#xD;
Think about your country and your workplace too: &#xD;
&#xD;
- Are there thought leaders, education revolutionaries or forward-thinking math education projects the CBM team should know about? &#xD;
&#xD;
I&amp;#039;m looking forward to your comments...and maybe see you in London!&#xD;
&#xD;
[![CBM Summit, London, 19-20 November][5]][6]&#xD;
&#xD;
&#xD;
  [1]: /c/portal/getImageAttachment?filename=_thumb_117376.png&amp;amp;userId=383623&#xD;
  [2]: https://www.computerbasedmath.org/&#xD;
  [3]: http://www.computerbasedmath.org/events/maths-education-summit-2015/&#xD;
  [4]: https://www.youtube.com/watch?v=NZvttwpeVrc&amp;amp;list=PLzKFBYmW-UKpLGkkprg5LkHUVPaCV85R1&amp;amp;index=35&#xD;
  [5]: /c/portal/getImageAttachment?filename=SummitFooterFullSize.jpg&amp;amp;userId=383623&#xD;
  [6]: http://www.computerbasedmath.org/events/maths-education-summit-2015/</description>
    <dc:creator>Richard Asher</dc:creator>
    <dc:date>2015-08-20T15:52:37Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/2030201">
    <title>[WSS20] Implementation of level-index arithmetic for very large numbers</title>
    <link>https://community.wolfram.com/groups/-/m/t/2030201</link>
    <description>&amp;amp;[Wolfram Notebook][1]&#xD;
&#xD;
&#xD;
  [1]: https://www.wolframcloud.com/obj/e9934595-75e0-42eb-92bc-ae38528364a7&#xD;
&#xD;
&#xD;
  [Original]: https://www.wolframcloud.com/obj/ss8659/Published/WSS20-Level-Index-Arithmetic-5.nb</description>
    <dc:creator>Swastik Banerjee</dc:creator>
    <dc:date>2020-07-14T17:07:16Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/3241848">
    <title>Retrieval augmented generation with Wolfram Language</title>
    <link>https://community.wolfram.com/groups/-/m/t/3241848</link>
    <description>![Retrieval augmented generation (RAG) with Wolfram Language][1]&#xD;
&#xD;
&amp;amp;[Wolfram Notebook][2]&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=2024MainImage.png&amp;amp;userId=20103&#xD;
  [2]: https://www.wolframcloud.com/obj/14c589e5-b550-4534-abda-a0ea80da3e3f</description>
    <dc:creator>Kotaro Okazaki</dc:creator>
    <dc:date>2024-08-06T01:55:33Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1419096">
    <title>Mathematica++ A C++ Library with Sugar</title>
    <link>https://community.wolfram.com/groups/-/m/t/1419096</link>
    <description>I was working on a library for my simulations. The difficult part was the shape of its input and output requires sophisticated UI. So after few days of manipulation with `Manipulate` I switched back to C++/Qt based UI and Mathematica for computation. So I was working on a C++ library to interact with Mathematica using WSTP API. It is usable but, not yet complete, however nothing is ever complete.   I named it [`mathematica++`][1] and released it under FreeBSD License. it is hosted in gitlab. [gitlab project page][2].&#xD;
&#xD;
I don&amp;#039;t want to bloat this post, These are some of the examples copy pasted from the above links&#xD;
&#xD;
    symbol x(&amp;#034;x&amp;#034;);&#xD;
    value  res;&#xD;
    std::string method = &amp;#034;Newton&amp;#034;;&#xD;
    &#xD;
    shell &amp;lt;&amp;lt; Values(FindRoot(ArcTan(1000 * Cos(x)), List(x, 1, 2),  Rule(&amp;#034;Method&amp;#034;) = method));&#xD;
    shell &amp;gt;&amp;gt; res;&#xD;
    std::vector&amp;lt;double&amp;gt; results = cast&amp;lt;std::vector&amp;lt;double&amp;gt;&amp;gt;(res);&#xD;
    std::cout &amp;lt;&amp;lt; results[0] &amp;lt;&amp;lt; std::endl; // Prints 10.9956&#xD;
&#xD;
Example 2&#xD;
&#xD;
    mathematica::m mata = Table(Mod(i + j, 2), List(i, 1, 2), List(j, 1, 2));&#xD;
    mathematica::m matb = Table(Mod(i + j, 3), List(i, 1, 2), List(j, 1, 2)];&#xD;
    mathematica::m matc = Dot(mata, matb);&#xD;
    mathematica::m matd = Det(matc);&#xD;
    &#xD;
    // Execute mathematica constructs and fetch the response&#xD;
    shell &amp;lt;&amp;lt; matd;&#xD;
    shell &amp;gt;&amp;gt; determinant;&#xD;
    &#xD;
    // determinant can be converted to C++ machine sized types&#xD;
    std::cout &amp;lt;&amp;lt; determinant &amp;lt;&amp;lt; std::endl; // Prints -2&#xD;
&#xD;
`cast&amp;lt;T&amp;gt;` brings the output returned by mathematica to STL containers&#xD;
&#xD;
    value result;&#xD;
    typedef std::vector&amp;lt;std::vector&amp;lt;int&amp;gt;&amp;gt; ivv_type;&#xD;
    shell &amp;lt;&amp;lt; FactorInteger(2434500);&#xD;
    shell &amp;gt;&amp;gt; result;&#xD;
    ivv_type prime_powers = mathematica::cast&amp;lt;ivv_type&amp;gt;(result);&#xD;
    for(auto pp: prime_powers){&#xD;
        std::cout &amp;lt;&amp;lt; pp[0] &amp;lt;&amp;lt; &amp;#034; ^ &amp;#034; &amp;lt;&amp;lt; pp[1] &amp;lt;&amp;lt; std::endl;&#xD;
    }&#xD;
    // Prints the following output&#xD;
    // 2 ^ 2&#xD;
    // 3 ^ 2&#xD;
    // 5 ^ 3&#xD;
    // 541 ^ 1&#xD;
&#xD;
Not limited to `std::vector` only&#xD;
&#xD;
Thank You.&#xD;
&#xD;
  [1]: http://neelex.com/mathematica++&#xD;
  [2]: https://gitlab.com/neel.basu/mathematicapp</description>
    <dc:creator>Neel Basu</dc:creator>
    <dc:date>2018-08-22T12:09:39Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1066381">
    <title>Computational implementation of the German Enigma Machine</title>
    <link>https://community.wolfram.com/groups/-/m/t/1066381</link>
    <description>![enter image description here][1]&#xD;
&#xD;
Below is an implementation of the German Enigma Machine which the German forces used to communicate encrypted messages during WWII. The machine was an ingenious design. It used a series of rotors and an elaborate electromechanical coupling to encrypt messages in German.&#xD;
&#xD;
About the mechanism, the first rotor moved with each click of the keyboard; the second rotor moved once the first rotor completed 26 moves or one complete turn; and the third rotor once the first moved 26*26 steps (one can easily understand where this is going).&#xD;
&#xD;
Since the rotors could move during the encryption process the key to deciphering the text was the &amp;#034;key&amp;#034; or the initial state of the rotors. The code was finally broken by a team of cryptographers at Bletchley Park led by Alan Turing. Some believe this caused the war to shorten by a few years. A movie titled &amp;#034;The Imitation Game&amp;#034; was released in 2014 highlighting this code breaking feat.&#xD;
&#xD;
    ClearAll@rotateWheel;&#xD;
    SetAttributes[rotateWheel, HoldFirst];&#xD;
    rotateWheel[wheel_] := Block[{},&#xD;
       wheel = RotateLeft[wheel]];&#xD;
&#xD;
The immediate block of code above enables me to make in-place modification i.e. to rotate and preserve the state of the rotors.&#xD;
&#xD;
    EnigmaEncryption[string_, staterot1_, staterot2_, staterot3_] := &#xD;
     Module[{count = 0, RotorIn, leftRotor, middleRotor, rightRotor, reflector, reflectorOutput,&#xD;
    rotateMiddleCheck, rotateRightCheck, inputToNext, reverseOutput},&#xD;
      RotorIn = ToLowerCase@CharacterRange[&amp;#034;A&amp;#034;, &amp;#034;Z&amp;#034;];&#xD;
      {leftRotor, middleRotor, rightRotor} = MapThread[Function[{x, y}, (z \[Function] &#xD;
            RotateLeft[z, First@Position[z, ToLowerCase@y] - 1])@&#xD;
          Characters@ToLowerCase[x]], {{&amp;#034;BDFHJLCPRTXVZNYEIWGAKMUSQO&amp;#034;, &#xD;
          &amp;#034;AJDKSIRUXBLHWTMCQGZNPYFVOE&amp;#034;, &amp;#034;EKMFLGDQVZNTOWYHXUSPAIBRCJ&amp;#034;},&#xD;
         {staterot1, staterot2, staterot3}}];&#xD;
&#xD;
      reflector = Characters@ToLowerCase@&amp;#034;YRUHQSLDPXNGOKMIEBFZCWVJAT&amp;#034;;&#xD;
      &#xD;
      inputToNext[rotor_, input_] :=  First@Cases[Thread[{RotorIn, rotor}], {input, map_} :&amp;gt; map ];&#xD;
      reverseOutput[rotor_, input_] := First@Cases[Thread[{RotorIn, rotor}], {map_, input} :&amp;gt; map ];&#xD;
      rotateMiddleCheck := If[count~Mod~26 == 0, rotateWheel@middleRotor, middleRotor];&#xD;
      rotateRightCheck := If[count~Mod~676 == 0, rotateWheel@rightRotor, rightRotor];&#xD;
      &#xD;
       StringJoin@Table[&#xD;
         If[FreeQ[input, Alternatives[&amp;#034; &amp;#034;, &amp;#034;,&amp;#034;, &amp;#034;&amp;#039;&amp;#034;, &amp;#034;?&amp;#034; ]],&#xD;
          count += 1;&#xD;
          reflectorOutput = &#xD;
           Fold[inputToNext[#2, #1] &amp;amp;,  input, {rotateWheel@leftRotor, rotateMiddleCheck, rotateRightCheck, reflector}];&#xD;
          Fold[reverseOutput[#2, #1] &amp;amp;, reflectorOutput, {rightRotor, middleRotor, leftRotor}], input]&#xD;
         , {input, Characters@ToLowerCase@string}]&#xD;
      ]&#xD;
&#xD;
 Now lets assume that the Germans encrypt a message with state &amp;#034;A&amp;#034;, &amp;#034;A&amp;#034;,&amp;#034;A&amp;#034; for the three moving rotors:&#xD;
&#xD;
    Style[text =  EnigmaEncryption[&amp;#034;this is the SS, Identify yourself, are you a German or are you Alan Turing?&amp;#034;, &amp;#034;A&amp;#034;, &amp;#034;A&amp;#034;, &amp;#034;A&amp;#034;], {Bold, FontSize -&amp;gt; 24}]&#xD;
&#xD;
**uubf jw dif oo, jctjgmbn nbtqrang, pvs vsh o orgiya lq lyw svn ssui zcxuxs?**&#xD;
&#xD;
If the cryptographers at Bletchley have the incorrect key &amp;#034;B&amp;#034;,&amp;#034;A&amp;#034;,&amp;#034;E&amp;#034; they will not be able to decipher the text (it will be gibberish).&#xD;
&#xD;
    Style[EnigmaEncryption[text, &amp;#034;B&amp;#034;, &amp;#034;A&amp;#034;, &amp;#034;E&amp;#034;], {Bold, FontSize -&amp;gt; 24}]&#xD;
&#xD;
**pgyy yd gnu nw, etlisxnw fnkniizh, tgy wde u gqkabx ma foe alc aifb cmavmt?**&#xD;
&#xD;
However, with the right key:&#xD;
&#xD;
    Style[EnigmaEncryption[text, &amp;#034;A&amp;#034;, &amp;#034;A&amp;#034;, &amp;#034;A&amp;#034;], {Bold, FontSize -&amp;gt;  24}] &#xD;
**this is the ss, identify yourself, are you a german or are you alan turing?**&#xD;
&#xD;
We can make a small animation of the rotor states. For visual purposes, blue represents the forward states of the system and red the backward state.&#xD;
 &#xD;
![enter image description here][1]&#xD;
&#xD;
&#xD;
&#xD;
the code below can be used to generate the animation sequence:&#xD;
&#xD;
    list = (Rasterize@*Grid /@ &#xD;
        Module[{out, states, mergedstates, rotorstates, riffle, first, last, text = text,&#xD;
          textout = StringReplace[text[[1]], Alternatives[&amp;#034; &amp;#034;, &amp;#034;,&amp;#034;, &amp;#034;&amp;#039;&amp;#034;, &amp;#034;?&amp;#034;] :&amp;gt; &amp;#034;&amp;#034;]},&#xD;
         out = Characters@textout;&#xD;
         states = Partition[text[[2, 1]], 7];&#xD;
         mergedstates =  Table[Join[states[[i]], {out[[i]]}], {i, Length@states}];&#xD;
         rotorstates = text[[2, 2]];&#xD;
         riffle = MapAt[Reverse, (Partition[#, 4] &amp;amp; /@ mergedstates), {All, 2}];&#xD;
         riffle = Apply[Composition[Partition[#, 2] &amp;amp;, Riffle], riffle, {1}];&#xD;
         Do[{first, last} = Flatten@Position[rotorstates[[j, i]], #] &amp;amp; /@ riffle[[j, i]];&#xD;
          rotorstates[[j, i, first]] = Style[First@rotorstates[[j, i, first]], {Blue, Bold, Background -&amp;gt; LightBlue}];&#xD;
          rotorstates[[j, i, last]] = Style[First@rotorstates[[j, i, last]], {Red, Bold,  Background -&amp;gt; LightRed}];&#xD;
          , {j, Length@riffle}, {i, 4}];&#xD;
         rotorstates&#xD;
         ]);&#xD;
&#xD;
&#xD;
  [1]: http://community.wolfram.com//c/portal/getImageAttachment?filename=1479animate.gif&amp;amp;userId=942204</description>
    <dc:creator>Ali Hashmi</dc:creator>
    <dc:date>2017-04-20T02:10:34Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/2416125">
    <title>Wolfram quantum computation framework: a few examples</title>
    <link>https://community.wolfram.com/groups/-/m/t/2416125</link>
    <description>&amp;amp;[Wolfram Notebook][1]&#xD;
&#xD;
&#xD;
  [1]: https://www.wolframcloud.com/obj/a5d46446-4ecd-4c49-9f10-57561e3961a5</description>
    <dc:creator>Mohammad Bahrami</dc:creator>
    <dc:date>2021-11-30T17:22:04Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1109273">
    <title>Chaos bifurcation of double pendulums calculation with OOP</title>
    <link>https://community.wolfram.com/groups/-/m/t/1109273</link>
    <description>This sample program is developed to show the power of [Mathematica OOP][1] as shown in other my OOP projects.&#xD;
&#xD;
It is well known that the double pendulum motion becomes a chaos with time development. Also, in the time development of a pendulum, we can observe another kind of chaos caused by the initial condition. A very small fluctuation of the initial condition affect the time development deeply. In this program case, angle perturbation less than 10^-12 can have an effect on the time development. &#xD;
&#xD;
To observe this phenomenon this program traces simultaneously a several tens of double pendulums each has random initial angle difference. The pendulums are represented by the instance constructed from the OOP Lagrange equation of motion class. The Mathematica OOP can represent these number of double pendulums motion in time development with a simple and an effective way. &#xD;
&#xD;
![50 pendulums in time development][2]&#xD;
&#xD;
Setup for global parameters and OOP class&#xD;
&#xD;
    {g = 9.8, m = 1, r1 = 1, r2 = 0.5, time = 50};&#xD;
    &#xD;
    case[nam_] := &#xD;
      Module[{\[Theta]1, \[Theta]2, ans, T1, T2, V1, V2, t, L, lkeq, &#xD;
        initcond},&#xD;
       &#xD;
       initialize[nam[th1_, th2_]] ^:= (&#xD;
         (* Lagrangian setup *)&#xD;
         T1 = 1/2 m*r1^2*\[Theta]1&amp;#039;[t]^2;&#xD;
         V1 = -m*g*r1*Cos[\[Theta]1[t]];&#xD;
         T2 = &#xD;
          1/2 m*(r1^2*\[Theta]1&amp;#039;[t]^2 + r2^2*\[Theta]2&amp;#039;[t]^2 + &#xD;
             2 r1*r2*\[Theta]1&amp;#039;[t]*\[Theta]2&amp;#039;[t]*r1*r2*&#xD;
              Cos[\[Theta]1[t] - \[Theta]2[t]]);&#xD;
         V2 = -m*g*(r1*Cos[\[Theta]1[t]] + r2*Cos[\[Theta]2[t]]);&#xD;
         L = T1 + T2 - (V1 + V2);&#xD;
         &#xD;
         (* Lagrange equation of motion *)&#xD;
         &#xD;
         lkeq = {D[D[L, \[Theta]1&amp;#039;[t]], t] - D[L, \[Theta]1[t]] == 0,&#xD;
           D[D[L, \[Theta]2&amp;#039;[t]], t] - D[L, \[Theta]2[t]] == 0};&#xD;
         initcond = {&#xD;
           \[Theta]1[0] == th1,&#xD;
           \[Theta]2[0] == th2,&#xD;
           \[Theta]1&amp;#039;[0] == 0,&#xD;
           \[Theta]2&amp;#039;[0] == 0};&#xD;
         &#xD;
         (* Numerical solve of equation *)&#xD;
         &#xD;
         ans = NDSolve[{lkeq, initcond}, {\[Theta]1, \[Theta]2}, {t, 0, &#xD;
             time}, MaxSteps -&amp;gt; Infinity, PrecisionGoal -&amp;gt; \[Infinity]][[&#xD;
           1]];&#xD;
         );&#xD;
       &#xD;
       pendulum[nam[tr_]] ^:= (&#xD;
         (* Pendulum graphics return *)&#xD;
         &#xD;
         Graphics[{Line[{{0, &#xD;
              0}, {r1*Sin[\[Theta]1[tr]], -r1*Cos[\[Theta]1[tr]]} /. &#xD;
              ans}], Line[{{r1*Sin[\[Theta]1[tr]], -r1*&#xD;
                Cos[\[Theta]1[tr]]}, {(r1*Sin[\[Theta]1[tr]] + &#xD;
                 r2*Sin[\[Theta]2[tr]]), (-r1*Cos[\[Theta]1[tr]] - &#xD;
                 r2*Cos[\[Theta]2[tr]])}} /. ans]}, &#xD;
          PlotRange -&amp;gt; {{-1.8, 1.8}, {-1.8, 1.8}}]&#xD;
         )&#xD;
       ];&#xD;
    &#xD;
Setup initial conditions and construct instances, and display of results&#xD;
&#xD;
    {pendulums = 50, angle1 = 4 Pi/3, angle2 = 4 Pi/3, butterfly = 10^-12};&#xD;
    &#xD;
    objectList = Table[Unique[], {pendulums}];&#xD;
    Map[case[#] &amp;amp;, objectList];&#xD;
    Map[initialize[#[angle1, angle2 + butterfly*RandomReal[{-1, 1}]]] &amp;amp;, &#xD;
      objectList];&#xD;
    &#xD;
    Animate[Show[&#xD;
      Map[pendulum[#[tr]] &amp;amp;, objectList]&#xD;
      ], {tr, 0, time}, AnimationRepetitions -&amp;gt; 1, AnimationRate -&amp;gt; 1]&#xD;
&#xD;
&#xD;
Enjoy a sudden divergence.&#xD;
&#xD;
&#xD;
  [1]: http://community.wolfram.com/groups/-/m/t/897081?p_p_auth=tO31eCls&#xD;
  [2]: http://community.wolfram.com//c/portal/getImageAttachment?filename=2302d-pendulum.jpg&amp;amp;userId=897049</description>
    <dc:creator>Hirokazu Kobayashi</dc:creator>
    <dc:date>2017-05-28T01:05:18Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1378496">
    <title>[WSS18] A Game Theory Package for the Wolfram Language</title>
    <link>https://community.wolfram.com/groups/-/m/t/1378496</link>
    <description>Theory of Games has an impressive development during the last 70 years both as a domain of applied mathematics and a part of various important domains of human activity. It&amp;#039;s somewhat strange that Mathematica doesn&amp;#039;t include any functionality related to game theory. Our project intends to initiate a game theory Mathematica package.&#xD;
&#xD;
At the first initiation stage of the project development, we consider strategic finite (multi-matrix) games and some solution concepts: Nash equilibrium, Stackelberg equilibrium, and MaxMin strategies:&#xD;
&#xD;
Game statement&#xD;
-------------------------------------&#xD;
&#xD;
A strategic game  is defined by the tuple:&#xD;
$$\Gamma = \langle N, \{X_i\}_{i\in N}, \{f_i (x)\}_{i\in N}\rangle,$$&#xD;
where $N=\{1,2,...,n\}$ is a set of players, $X_i$ is a set of strategies of player $i\in N$ and $f_i:X\rightarrow R$ is a&#xD;
player&amp;#039;s $i\in N$ payoff function defined on the Cartesian product $X = \times_{i \in N} X_i$. Elements of $X$ are called outcomes of&#xD;
the game (strategy profiles). &#xD;
&#xD;
An outcome $x^*\in X$ of is a Nash equilibrium (shortly NE) of $\Gamma$ if&#xD;
$$f_i ( x_i, x_{-i}^*) \le f_i ( x^*_i, x_{-i}^* ), \forall x_i \in X_i,\,\, \forall i \in N,$$&#xD;
where&#xD;
$$x_{-i}^* = (x^*_1, x^*_2, ..., x^*_{i-1}, x^*_{i+1}, ..., x^*_n),$$&#xD;
$$x_{-i}^* \in X_{-i}=X_1 \times X_2 \times ... \times X_{i-1} \times X_{i+1} \times ... \times X_n,$$&#xD;
$$(x_i,x_{-i}^*) = (x^*_1, x^*_2, ..., x^*_{i-1},x_i, x^*_{i+1}, ..., x^*_n)\in X.$$&#xD;
&#xD;
We study Nash equilibrium sets as an intersection of best response mapping graphs [5,1, 2], i.e. the intersection of the sets:&#xD;
$$Gr_i=\{(x_i,x_{-i})\in X: x_{-i}\in X_{-i}, x_i\in {\rm Arg}\max_{x_i\in X_i} f_i(x_i,x_{-i})\},\,\, i\in N.$$&#xD;
&#xD;
Theorem 1. The outcome $x^*\in X$ is a Nash equilibrium if and only if $x^*\in \bigcap_{i \in N}Gr_i$.&#xD;
&#xD;
Theorem 1 stands for a main method that we will use to find Nash equilibrium set. So, we are looking to finding Nash equilibrium sets as the intersection of best response mapping graphs, both in pure and mixed strategy games.&#xD;
&#xD;
Package design&#xD;
-------------------------------------&#xD;
We have designed package structure and features that have to be applied to all its functions, their titles and  options. Main functions of the package a `GameTheory[]` and `GameTheoryPlot[]`. There is an idea to recall them `GameSolve[]` and `GameSolvePlot[]`. Formal parameters of the functions are initial data of the games, as well all the concepts that specifies a concrete game theory problem:&#xD;
&#xD;
    testOptionValue[&amp;#034;Criteria&amp;#034; -&amp;gt; crit, {&amp;#034;Maximize&amp;#034;, &amp;#034;Minimize&amp;#034;}];&#xD;
&#xD;
    testOptionValue[&amp;#034;Strategy&amp;#034; -&amp;gt; type, {&amp;#034;Pure&amp;#034;, &amp;#034;Mixed&amp;#034;}];&#xD;
&#xD;
    testOptionValue[&amp;#034;Concept&amp;#034; -&amp;gt; concept, {&amp;#034;NashEquilibrium&amp;#034;, &amp;#034;MaxMin&amp;#034;, &amp;#034;StackelbergEquilibrium&amp;#034;}]&#xD;
&#xD;
We have created algorithms and corresponding codes that solve problems of Nash equilibrium set finding, as well as MaxMin solutions computing. In this context we need to mention the following functions:&#xD;
&#xD;
    pureNashEquilibria[matr_] := ...&#xD;
    &#xD;
    maxMin[matr_] :=...&#xD;
    &#xD;
    pureStackelbergEquilibria[matr_] :=...&#xD;
&#xD;
We have also programmed the code that solves two-matrix mixed strategy games.&#xD;
&#xD;
    mixedNashEquilibria[m_] := ...&#xD;
&#xD;
The package includes, withal, a function that plot Nash equilibrium set in $2\times 2$ mixed strategy games.&#xD;
&#xD;
    game2x2Plot[m_]:= ...&#xD;
&#xD;
Some private functions and their application&#xD;
-------------------------------------&#xD;
&#xD;
For the problem of Nash equilibrium set computing the main function is:&#xD;
&#xD;
    bestResponse[m_]:=With[{ind=indexSets[Dimensions[m[[1]]]]},&#xD;
    	Intersection@@Table[&#xD;
    		Flatten[&#xD;
    			Thread/@Table[&#xD;
    				Replace[i, All:&amp;gt;maxPositions@m[[player,Sequence@@i]], {1}],&#xD;
    				{i, Tuples[ind[[player]]]}&#xD;
    			],&#xD;
    			1&#xD;
    		],&#xD;
    		{player, Length[m]}&#xD;
    	]&#xD;
    ]&#xD;
    &#xD;
The notation `m` is for  payoff matrices of the players. `Length[m]` gives the number of players. `Tuples[]` gives all possible tuples formed by player strategies. `maxPositions[]` gives positions on which maximal values are obtained. The intersection of all `Length[m]` lists of players offers the set of Nash equilibria.&#xD;
&#xD;
In practice, this function is called by `GameTheory[]` as in the following examples:&#xD;
&#xD;
    In[1]:= Clear[a, b]&#xD;
    a = {{2, 2, 3}, {7, 2, 2}, {1, 1, 4}};&#xD;
    b = {{5, 6, 1}, {5, 2, 3}, {3, 5, 7}}; &#xD;
    MatrixForm /@ {a, b};&#xD;
    &#xD;
    In[2]:= GameTheory[{a, b}, Method -&amp;gt; {&amp;#034;Criteria&amp;#034; -&amp;gt; &amp;#034;Maximize&amp;#034;, &amp;#034;Concept&amp;#034; -&amp;gt; &amp;#034;NashEquilibrium&amp;#034;,  &amp;#034;Strategy&amp;#034; -&amp;gt; &amp;#034;Pure&amp;#034;}]&#xD;
    &#xD;
    Out[2]= {&amp;lt;|&amp;#034;Player 1&amp;#034; -&amp;gt; 1, &amp;#034;Player 2&amp;#034; -&amp;gt; 2|&amp;gt; -&amp;gt; {2,  6}, &amp;lt;|&amp;#034;Player 1&amp;#034; -&amp;gt; 2, &amp;#034;Player 2&amp;#034; -&amp;gt; 1|&amp;gt; -&amp;gt; {7, 5},  &amp;lt;|&amp;#034;Player 1&amp;#034; -&amp;gt; 3, &amp;#034;Player 2&amp;#034; -&amp;gt; 3|&amp;gt; -&amp;gt; {4, 7}}&#xD;
&#xD;
Another private function is:&#xD;
&#xD;
    (* ------ MaxMin strategies ------ *)&#xD;
    &#xD;
    maxMin[matr_]:=Module[{dim=Dimensions[matr[[1]]], min, ind, tuples, payoffTuples},(*matr\[LeftDoubleBracket]1\[RightDoubleBracket] has the same dimensions as all other m\[LeftDoubleBracket]2\[RightDoubleBracket],...,m\[LeftDoubleBracket]n\[RightDoubleBracket]*)&#xD;
    	Table[&#xD;
    	    min=Table[0,dim[[player]]];&#xD;
    		Do[&#xD;
    		    ind=Table[Range[dim[[j]]],{j,Length[matr]}];                (* list of strategy sets *)&#xD;
    			ind[[player]]={str};                                         (* strategy set of the player is set simply formed by one element: {str} *)&#xD;
    			tuples=Tuples[ind];                                           (* generate the tuples *)&#xD;
    			payoffTuples=Table[matr[[player,Sequence@@t]],{t,tuples}];   (* the variable player gives the matrix of the player; other indeces give the payoff value *)&#xD;
    			min[[str]]=Min[payoffTuples],                                 (* for every player *)&#xD;
    		 {str,dim[[player]]}&#xD;
    		];&#xD;
    		&amp;#034;Player &amp;#034;&amp;lt;&amp;gt;ToString[player] -&amp;gt; &amp;lt;|&amp;#034;Strategy&amp;#034;-&amp;gt;maxPositions[min],&amp;#034;Payoff&amp;#034;-&amp;gt;min[[maxPositions[min]]][[1]]|&amp;gt;,&#xD;
    	 {player,Length[matr]}&#xD;
    	]&#xD;
    ]&#xD;
&#xD;
It is used to compute MaxMin strategies. This concept is more simple in comparison with the Nash equilibrium. It needs finding for every fixed strategy of the player the worst response of the other players. After knowing all such worst responses, every player computes the best from them, that being the MaxMin strategy.&#xD;
&#xD;
The following example illustrates how the function is applied really for the same above matrices:&#xD;
&#xD;
    In[3]:= GameTheory[{a, b}, &#xD;
     Method -&amp;gt; {&amp;#034;Criteria&amp;#034; -&amp;gt; &amp;#034;Maximize&amp;#034;, &amp;#034;Concept&amp;#034; -&amp;gt; &amp;#034;MaxMin&amp;#034;, &#xD;
       &amp;#034;Strategy&amp;#034; -&amp;gt; &amp;#034;Pure&amp;#034;}]&#xD;
    &#xD;
    Out[3]= {&amp;#034;Player 1&amp;#034; -&amp;gt; &amp;lt;|&amp;#034;Strategy&amp;#034; -&amp;gt; {1, 2}, &amp;#034;Payoff&amp;#034; -&amp;gt; 2|&amp;gt;, &#xD;
     &amp;#034;Player 2&amp;#034; -&amp;gt; &amp;lt;|&amp;#034;Strategy&amp;#034; -&amp;gt; {1}, &amp;#034;Payoff&amp;#034; -&amp;gt; 3|&amp;gt;}&#xD;
&#xD;
Sure, the function solves the above problems for an arbitrary number of players:&#xD;
&#xD;
    ------------------------------------------------------------------ 5 player game ---------------------------------------------------------------&#xD;
    &#xD;
    In[4]:= Clear[a, b, c, d, e]&#xD;
    a = RandomInteger[{-10, 1000}, {5, 5, 5, 5, 5}];&#xD;
    b = RandomInteger[{-10, 1000}, {5, 5, 5, 5, 5}];&#xD;
    c = RandomInteger[{-10, 1000}, {5, 5, 5, 5, 5}];&#xD;
    d = RandomInteger[{-10, 1000}, {5, 5, 5, 5, 5}];&#xD;
    e = RandomInteger[{-10, 1000}, {5, 5, 5, 5, 5}];&#xD;
    MatrixForm /@ {a, b, c, d, e};&#xD;
    &#xD;
    In[5]:= GameTheory[{a, b, c, d, e}, &#xD;
     Method -&amp;gt; {&amp;#034;Criteria&amp;#034; -&amp;gt; &amp;#034;Maximize&amp;#034;, &amp;#034;Concept&amp;#034; -&amp;gt; &amp;#034;MaxMin&amp;#034;, &#xD;
       &amp;#034;Strategy&amp;#034; -&amp;gt; &amp;#034;Pure&amp;#034;}]&#xD;
    &#xD;
    Out[5]= {&amp;#034;Player 1&amp;#034; -&amp;gt; &amp;lt;|&amp;#034;Strategy&amp;#034; -&amp;gt; {5}, &amp;#034;Payoff&amp;#034; -&amp;gt; -7|&amp;gt;, &#xD;
     &amp;#034;Player 2&amp;#034; -&amp;gt; &amp;lt;|&amp;#034;Strategy&amp;#034; -&amp;gt; {1, 5}, &amp;#034;Payoff&amp;#034; -&amp;gt; -7|&amp;gt;, &#xD;
     &amp;#034;Player 3&amp;#034; -&amp;gt; &amp;lt;|&amp;#034;Strategy&amp;#034; -&amp;gt; {2}, &amp;#034;Payoff&amp;#034; -&amp;gt; -7|&amp;gt;, &#xD;
     &amp;#034;Player 4&amp;#034; -&amp;gt; &amp;lt;|&amp;#034;Strategy&amp;#034; -&amp;gt; {4}, &amp;#034;Payoff&amp;#034; -&amp;gt; -8|&amp;gt;, &#xD;
     &amp;#034;Player 5&amp;#034; -&amp;gt; &amp;lt;|&amp;#034;Strategy&amp;#034; -&amp;gt; {3}, &amp;#034;Payoff&amp;#034; -&amp;gt; -8|&amp;gt;}&#xD;
    &#xD;
    In[6]:= GameTheory[{a, b, c, d, e}, &#xD;
     Method -&amp;gt; {&amp;#034;Criteria&amp;#034; -&amp;gt; &amp;#034;Maximize&amp;#034;, &amp;#034;Concept&amp;#034; -&amp;gt; &amp;#034;NashEquilibrium&amp;#034;, &#xD;
       &amp;#034;Strategy&amp;#034; -&amp;gt; &amp;#034;Pure&amp;#034;}]&#xD;
    &#xD;
    Out[6]= {&amp;lt;|&amp;#034;Player 1&amp;#034; -&amp;gt; 1, &amp;#034;Player 2&amp;#034; -&amp;gt; 1, &amp;#034;Player 3&amp;#034; -&amp;gt; 2, &amp;#034;Player 4&amp;#034; -&amp;gt; 2, &#xD;
       &amp;#034;Player 5&amp;#034; -&amp;gt; 4|&amp;gt; -&amp;gt; {807, 935, 772, 829, 986}, &amp;lt;|&amp;#034;Player 1&amp;#034; -&amp;gt; 3, &#xD;
       &amp;#034;Player 2&amp;#034; -&amp;gt; 1, &amp;#034;Player 3&amp;#034; -&amp;gt; 5, &amp;#034;Player 4&amp;#034; -&amp;gt; 5, &#xD;
       &amp;#034;Player 5&amp;#034; -&amp;gt; 3|&amp;gt; -&amp;gt; {824, 939, 621, 776, 874}}&#xD;
&#xD;
It is important to remark here that not all pure strategy games have Nash equilibria. But, all mixed-strategy games have Nash equilibria.&#xD;
&#xD;
Next private function solve the problem of Nash equilibrium set finding in two-matrix mixed-strategy games:&#xD;
&#xD;
    mixedNashEquilibria[m_]:=With[{a=m[[1]],b=m[[2]]},&#xD;
    &#xD;
      NESet={};&#xD;
    &#xD;
      Do[&#xD;
         \[DoubleStruckCapitalU]=Range[i+1,Dimensions[a][[1]]];&#xD;
            Do[&#xD;
                  Do[&#xD;
                      If[X[b,i,j,\[DoubleStruckCapitalI],{}]==0,Break,Continue];&#xD;
                      \[DoubleStruckCapitalV]=Range[j+1,Dimensions[a][[2]]];&#xD;
                           Do[                                            &#xD;
                                If[Y[a,i,j,\[DoubleStruckCapitalI],\[DoubleStruckCapitalJ]]!=0&amp;amp;&amp;amp;X[b,i,j,\[DoubleStruckCapitalI],\[DoubleStruckCapitalJ]]!=0,&#xD;
                                          NESet=AppendTo[NESet,{XOut[b,i,j,\[DoubleStruckCapitalI],\[DoubleStruckCapitalJ]],YOut[a,i,j,\[DoubleStruckCapitalI],\[DoubleStruckCapitalJ]]}],&#xD;
                                          Break&#xD;
                                 ],&#xD;
                            {\[DoubleStruckCapitalJ],Subsets[\[DoubleStruckCapitalV]]}&#xD;
                           ],&#xD;
                   {j,Dimensions[a][[2]]}&#xD;
                  ],&#xD;
             {\[DoubleStruckCapitalI],Subsets[\[DoubleStruckCapitalU]]}&#xD;
            ],&#xD;
       {i,Dimensions[a][[1]]}&#xD;
      ];&#xD;
      DeleteDuplicates@NESet&#xD;
    ]&#xD;
&#xD;
The intersection method used for two-matrix mixed strategy games is described in details in [2]. Next, we illustrate its working out in the above form codding:&#xD;
&#xD;
    Clear[a, b]&#xD;
    a = {{2, 2, 3}, {7, 2, 2}, {1, 1, 4}};&#xD;
    b = {{5, 6, 1}, {5, 2, 3}, {3, 5, 7}}; &#xD;
    MatrixForm /@ {a, b};&#xD;
&#xD;
![enter image description here][1]&#xD;
&#xD;
For some strategic games it is possible to present graphically the set of Nash equilibria [6].&#xD;
&#xD;
All the code is very large, so we present here only on function used to manipulate all graphics objects appearing in the final image:&#xD;
&#xD;
    game2x2Plot[m_]:=Module[{matr=m},&#xD;
    				 {{{\[DoubleStruckA]11,\[DoubleStruckA]12},{\[DoubleStruckA]21,\[DoubleStruckA]22}},{{\[DoubleStruckB]11,\[DoubleStruckB]12},{\[DoubleStruckB]21,\[DoubleStruckB]22}}}=matr;&#xD;
    			    Manipulate[&#xD;
    					Grid[{{Graphics[{Thick,&#xD;
    						Blue,g1[a11-a12-a21+a22,a12-a22],&#xD;
    						Green,g2[b11-b12-b21+b22,b21-b22],&#xD;
    						Red,PointSize[Large],nes[a11-a12-a21+a22,a12-a22,b11-b12-b21+b22,b21-b22]},&#xD;
    						PlotRange-&amp;gt;{{0,1},{0,1}},Axes-&amp;gt;True,AxesLabel-&amp;gt;{&amp;#034;\!\(\*SubscriptBox[\(x\), \(1\)]\)&amp;#034;,&amp;#034;\!\(\*SubscriptBox[\(y\), \(1\)]\)&amp;#034;},&#xD;
    						ImageSize-&amp;gt;{300,300}]},{&amp;#034; &amp;#034;},{Text@Style[&amp;#034;Reference Nash Equilibria&amp;#034;,Bold]},&#xD;
    						{Text@Style[nes[a11-a12-a21+a22,a12-a22,b11-b12-b21+b22,b21-b22][[1,1]],Bold]}},ItemSize-&amp;gt;{Automatic,{10,1,1,3}},Alignment-&amp;gt;{Center,Top}&#xD;
    					],&#xD;
    						Style[&amp;#034;Matrix A&amp;#034;,Bold],&#xD;
    						{{a11,\[DoubleStruckA]11,&amp;#034;\!\(\*SubscriptBox[\(a\), \(11\)]\)&amp;#034;},-10,10,1,Appearance-&amp;gt; &amp;#034;Labeled&amp;#034;,ImageSize-&amp;gt;Tiny},&#xD;
    						{{a12,\[DoubleStruckA]12,&amp;#034;\!\(\*SubscriptBox[\(a\), \(12\)]\)&amp;#034;},-10,10,1,Appearance-&amp;gt; &amp;#034;Labeled&amp;#034;,ImageSize-&amp;gt;Tiny},&#xD;
    						{{a21,\[DoubleStruckA]21,&amp;#034;\!\(\*SubscriptBox[\(a\), \(21\)]\)&amp;#034;},-10,10,1,Appearance-&amp;gt; &amp;#034;Labeled&amp;#034;,ImageSize-&amp;gt;Tiny},&#xD;
    						{{a22,\[DoubleStruckA]22,&amp;#034;\!\(\*SubscriptBox[\(a\), \(22\)]\)&amp;#034;},-10,10,1,Appearance-&amp;gt; &amp;#034;Labeled&amp;#034;,ImageSize-&amp;gt;Tiny},&#xD;
    						Delimiter,{{NonAntagonistic,True, &amp;#034;NonAntagonistic&amp;#034;},{True,False}},&#xD;
    						Delimiter,Style[&amp;#034;Matrix B&amp;#034;,Bold],&#xD;
    						{{b11,\[DoubleStruckB]11,&amp;#034;\!\(\*SubscriptBox[\(b\), \(11\)]\)&amp;#034;},-10,10,1,Enabled-&amp;gt;NonAntagonistic,Appearance-&amp;gt; &amp;#034;Labeled&amp;#034;,ImageSize-&amp;gt;Tiny},&#xD;
    						{{b12,\[DoubleStruckB]12,&amp;#034;\!\(\*SubscriptBox[\(b\), \(12\)]\)&amp;#034;},-10,10,1,Enabled-&amp;gt;NonAntagonistic,Appearance-&amp;gt; &amp;#034;Labeled&amp;#034;,ImageSize-&amp;gt;Tiny},&#xD;
    						{{b21,\[DoubleStruckB]21,&amp;#034;\!\(\*SubscriptBox[\(b\), \(21\)]\)&amp;#034;},-10,10,1,Enabled-&amp;gt;NonAntagonistic,Appearance-&amp;gt; &amp;#034;Labeled&amp;#034;,ImageSize-&amp;gt;Tiny},&#xD;
    						{{b22,\[DoubleStruckB]22,&amp;#034;\!\(\*SubscriptBox[\(b\), \(22\)]\)&amp;#034;},-10,10,1,Enabled-&amp;gt;NonAntagonistic,Appearance-&amp;gt; &amp;#034;Labeled&amp;#034;,ImageSize-&amp;gt;Tiny},&#xD;
    						Delimiter,&#xD;
    						Style[&amp;#034;Matrices A and B&amp;#034;,Bold],&#xD;
    					Dynamic[&#xD;
    						TableForm[&#xD;
    							{{ToString[a11]&amp;lt;&amp;gt;&amp;#034; , &amp;#034;&amp;lt;&amp;gt;ToString[If[NonAntagonistic,b11,b11=-a11]],&#xD;
    							ToString[a12]&amp;lt;&amp;gt;&amp;#034; , &amp;#034;&amp;lt;&amp;gt;ToString[If[NonAntagonistic,b12,b12=-a12]]},&#xD;
    							{ToString[a21]&amp;lt;&amp;gt;&amp;#034; , &amp;#034;&amp;lt;&amp;gt;ToString[If[NonAntagonistic,b21,b21=-a21]],&#xD;
    							ToString[a22]&amp;lt;&amp;gt;&amp;#034; , &amp;#034;&amp;lt;&amp;gt;ToString[If[NonAntagonistic,b22,b22=-a22]]}},&#xD;
    							TableHeadings-&amp;gt;{{&amp;#034;1&amp;#034;,&amp;#034;2&amp;#034;},{&amp;#034;  1&amp;#034;,&amp;#034;  2&amp;#034;}},&#xD;
    						  TableSpacing-&amp;gt;{2,2}&#xD;
    						]&#xD;
    					],&#xD;
    					SaveDefinitions-&amp;gt;True&#xD;
    				]&#xD;
    ]&#xD;
&#xD;
In practice, the function is used at it follows:&#xD;
&#xD;
        Clear[a, b]&#xD;
        a = {{5, 3}, {7, 2}};&#xD;
        b = {{3, 6}, {5, 3}}; &#xD;
        MatrixForm /@ {a, b};&#xD;
        GameTheoryPlot[{a, b}]&#xD;
&#xD;
![enter image description here][2]&#xD;
&#xD;
Conclusions&#xD;
-------------------------------------&#xD;
We have passed only a first pre-initial state of the package construction. There is a lot of things that must be done to establish a successful game theory package. We can only emphasised here some other stages. So, we intend to develop the package in several successive stages and directions:&#xD;
&#xD;
 1. At the first initiation stage we plan to enlarge the number of strategic form game theory problems solved by the package, and to include more plotting possibilities.&#xD;
 2. At the second stage we intend to develop package functionality in order to solve extensive form games, and to include their abundant plotting functionality.&#xD;
 3. At the third stage, we are considering adding support for cooperative games.&#xD;
 4. At the fourth stage, we plan to consider differential games and control.&#xD;
 5. Next stages will include multi-criteria mixtures of simultaneous and sequential games, as well as a lot of applied problems from all the human activity.&#xD;
&#xD;
Bibliography&#xD;
-----------&#xD;
 1. [Ungureanu, Valeriu, Nash equilibria set computing in finite extended games, CSJM, 2006, Vol. 14, No. 3 (42), pp. 345-365.][3]&#xD;
 2. [Ungureanu, Valeriu, &amp;#034;Pareto-Nash-Stackelberg Game and Control Theory&amp;#034;, Springer International Publishing, 2018, XXI + 343 pp.][4]&#xD;
 3. [Ungureanu, Valeriu, Nash equilibrium set function in dyadic mixed-strategy games, CSJM v .25, n .1 (73), 2017.][5]&#xD;
 4. [Nash J.F., Noncooperative game, Annals of Mathematics, 54, 1951, pp. 280-295.][6]&#xD;
 5. Sagaidac, M., and Ungureanu, V., Operational research, Chi\sinau, CEP USM, 2004, 296 p. (in Romanian)&#xD;
 6. [Ungureanu, V., Nash Equilibrium Sets in Dyadic Bimatrix Mixed-Strategy Games,][7] &#xD;
&#xD;
&#xD;
  [1]: http://community.wolfram.com//c/portal/getImageAttachment?filename=TwoMatrixMixedStrategyGame.png&amp;amp;userId=159033&#xD;
  [2]: http://community.wolfram.com//c/portal/getImageAttachment?filename=game2x2Image.png&amp;amp;userId=159033&#xD;
  [3]: http://www.math.md/files/csjm/v14-n3/v14-n3-%28pp345-365%29.pdf&#xD;
  [4]: https://www.springer.com/gp/book/9783319751504&#xD;
  [5]: http://www.math.md/files/csjm/v25-n1/v25-n1-%28pp3-20%29.pdf&#xD;
  [6]: https://www.jstor.org/stable/1969529?seq=1#page_scan_tab_contents&#xD;
  [7]: http://community.wolfram.com/groups/-/m/t/892544?p_p_auth=LiMRfo3d</description>
    <dc:creator>Valeriu Ungureanu</dc:creator>
    <dc:date>2018-07-11T16:36:01Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1112012">
    <title>BVH Accelerated 3D Shadow Mapping</title>
    <link>https://community.wolfram.com/groups/-/m/t/1112012</link>
    <description>[Shadow mapping][1] is a process of applying shadows to a computer graphic.  `Graphics3D` allows the user to specify lighting conditions for the surfaces of 3D graphical primitives, however, visualising the shadow an object projects onto a surface requires the processes of shadow mapping.  Each pixel of the projection surface must check if it is visible from the light source; if this check returns false then the pixel forms a shadow.  This becomes a problem of geometric intersections, i.e., for this case, the intersection between a line and a triangle.  For a 3D model with 100s and more of polygons, repeated intersection tests across the entire model for each pixel is an extremely costly (and inefficient) task.  Now this becomes a problem of search optimisation.    &#xD;
&#xD;
![enter image description here][2]&#xD;
&#xD;
&#xD;
Obtaining Data&#xD;
--------------&#xD;
&#xD;
This project uses 3D models from [SketchUp&amp;#039;s online repository][3] which are converted to COLLADA files using SketchUp.  The functions used are held in a package, accessible via [github][4] along with all the data referenced throughout.&#xD;
&#xD;
    (* load package and 3D model *)&#xD;
    &amp;lt;&amp;lt; &amp;#034;https://raw.githubusercontent.com/b-goodman/\&#xD;
    GeometricIntersections3D/master/GeometricIntersections3D.wl&amp;#034;;&#xD;
    &#xD;
    modelPath = &#xD;
      &amp;#034;https://raw.githubusercontent.com/b-goodman/\&#xD;
    GeometricIntersections3D/master/Demo/House/houseModel4.dae&amp;#034;;&#xD;
    &#xD;
    (* vertices of model&amp;#039;s polygons *)&#xD;
    polyPoints = Delete[0]@Import[modelPath, &amp;#034;PolygonObjects&amp;#034;];&#xD;
    &#xD;
    (* import model as region *)&#xD;
    modelRegion = Import[modelPath, &amp;#034;MeshRegion&amp;#034;];&#xD;
    &#xD;
    (* use region to generate minimal bounding volume *)&#xD;
    cuboidPartition = Delete[0]@BoundingRegion[modelRegion, &amp;#034;MinCuboid&amp;#034;];&#xD;
    &#xD;
    (* verify *)&#xD;
    Graphics3D[{&#xD;
      Polygon[polyPoints],&#xD;
      {Hue[0, 0, 0, 0], EdgeForm[Black], Cuboid[cuboidPartition]}&#xD;
      }, Boxed -&amp;gt; False]&#xD;
&#xD;
![imported model data][5]&#xD;
&#xD;
Generate a Bounding Volume Hierarchy (BVH)&#xD;
------------------------------------------&#xD;
&#xD;
Shadow mapping (and more generally collision testing) may be optimised via space partitioning achieved by dividing the 3D model&amp;#039;s space into a hierarchy of bounding volumes (BV) stored as a graph, thus forming a [bounding volume hierarchy][6].  The simplest case uses the result of an intersection between a ray and a single BV for the entire model to discard all rays which don&amp;#039;t come close to any of the model&amp;#039;s polygons.  Of course, those which do pass the first test must still be tested against the entire model so the initial BV is subdivided with each sub BV assigned to a particular part of the model hence reducing the total amount of polygons to be tested against.  The initial BV forms the root of the tree and it&amp;#039;s subdivisions (leaf boxes) are joined via edges.  We can add more levels to the tree by repeating the subdivision for each of the leaf boxes and ultimately refining the search for potential intersecting polygons.   &#xD;
&#xD;
    (* Begin tree.  Initial AABB is root.  Subdivide root AABB and link returns to root *) &#xD;
    newBVH[cuboidPartitions_,polyPoints_]:=Block[{&#xD;
    newLevel,edges&#xD;
    },&#xD;
    newLevel=Quiet[cullIntersectingPartitions[cuboidSubdivide[cuboidPartitions],polyPoints]];&#xD;
    edges=cuboidPartitions\[DirectedEdge]#&amp;amp;/@newLevel;&#xD;
    Return[&amp;lt;|&#xD;
    &amp;#034;Tree&amp;#034;-&amp;gt;TreeGraph[edges],&#xD;
    &amp;#034;PolygonObjects&amp;#034;-&amp;gt;polyPoints&#xD;
    |&amp;gt;];&#xD;
    ];&#xD;
&#xD;
    bvh = newBVH[{cuboidPartition}, polyPoints];&#xD;
    &#xD;
The BVH is a tree graph with the model&amp;#039;s polygon vertices encapsulated within an association&#xD;
&#xD;
    Keys[bvh]&#xD;
    &#xD;
    {&amp;#034;Tree&amp;#034;, &amp;#034;PolygonObjects&amp;#034;}&#xD;
    &#xD;
The BVH consists of a root box derived from the model&amp;#039;s minimal  bounding volume and it&amp;#039;s 8 sub-divisions &#xD;
&#xD;
    bvh[&amp;#034;Tree&amp;#034;]&#xD;
&#xD;
![enter image description here][7]&#xD;
&#xD;
The boxes at the lowest level of the BVH are the leaf boxes &#xD;
&#xD;
    leafBoxesLV1 = &#xD;
      Select[VertexList[bvh[&amp;#034;Tree&amp;#034;]], &#xD;
       VertexOutDegree[bvh[&amp;#034;Tree&amp;#034;], #] == 0 &amp;amp;];&#xD;
    &#xD;
    Graphics3D[{&#xD;
      Polygon[polyPoints],&#xD;
      {Hue[0, 0, 0, 0], EdgeForm[Black], Cuboid /@ leafBoxesLV1}&#xD;
      }, Boxed -&amp;gt; False]&#xD;
&#xD;
![enter image description here][8]&#xD;
&#xD;
Adding a new level sub-divides each leaf box into 8 sub-divisions. &#xD;
&#xD;
    With[{&#xD;
      testCuboid = {{0, 0, 0}, {10, 10, 10}}&#xD;
      },&#xD;
     Manipulate[&#xD;
      Graphics3D[{&#xD;
        If[n == 0, Cuboid[testCuboid], &#xD;
         Cuboid /@ Nest[cuboidSubdivide, testCuboid, n]]&#xD;
        }, Boxed -&amp;gt; False, Axes -&amp;gt; {True, False}],&#xD;
      {{n, 0}, 0, 4, 1}&#xD;
      ]&#xD;
     ]&#xD;
&#xD;
![enter image description here][9]&#xD;
&#xD;
The time needed for each addition to the BVH increases dramatically.&#xD;
&#xD;
    Length /@ NestList[cuboidSubdivide, {{{0, 0, 0}, {1, 1, 1}}}, 5]&#xD;
    &#xD;
     {1, 8, 64, 512, 4096, 32768}&#xD;
&#xD;
1-2 added levels is usually enough for the models used in this project.&#xD;
&#xD;
    (* Each new subdivision acts as root.  For each, subdivide further and remove any non-intersecting boxes.  Link back to parent box as directed edge *)&#xD;
    addLevelBVH[BVH_]:=Block[{&#xD;
    tree=BVH[&amp;#034;Tree&amp;#034;],polyPoints=BVH[&amp;#034;PolygonObjects&amp;#034;],returnEdges&#xD;
    },&#xD;
    Module[{&#xD;
    subEdges=Map[&#xD;
    Function[{levelComponent},levelComponent\[DirectedEdge]#&amp;amp;/@Quiet@cullIntersectingPartitions[cuboidSubdivide[levelComponent],polyPoints]],&#xD;
    Pick[VertexList[tree],VertexOutDegree[tree],0]]&#xD;
    },&#xD;
    returnEdges=ConstantArray[0,Length[subEdges]];&#xD;
    Do[returnEdges[[i]]=EdgeAdd[tree,subEdges[[i]]],{i,1,Length[subEdges],1}];&#xD;
    ];&#xD;
    returnEdges=DeleteDuplicates[Flatten[Join[EdgeList/@returnEdges]]];&#xD;
    Return[&amp;lt;|&#xD;
    &amp;#034;Tree&amp;#034;-&amp;gt;TreeGraph[returnEdges],&#xD;
    &amp;#034;PolygonObjects&amp;#034;-&amp;gt;polyPoints&#xD;
    |&amp;gt;]&#xD;
    ];&#xD;
&#xD;
 &#xD;
    bvh2 = addLevelBVH[bvh];&#xD;
    bvh2[&amp;#034;Tree&amp;#034;]&#xD;
&#xD;
![enter image description here][10]&#xD;
&#xD;
Any subs which don&amp;#039;t intersect with the model don&amp;#039;t contribute to the BVH and so are removed as part of the process.&#xD;
&#xD;
    cullIntersectingPartitions=Compile[{&#xD;
    {cuboidPartitions,_Real,3},&#xD;
    {polyPoints,_Real,3}&#xD;
    },&#xD;
    Select[cuboidPartitions,Function[{partitions},MemberQ[ParallelMap[Quiet@intersectTriangleBox[partitions,#]&amp;amp;,polyPoints],True]]],&#xD;
    CompilationTarget-&amp;gt;&amp;#034;C&amp;#034;&#xD;
    ];&#xD;
&#xD;
&#xD;
Visualising the leaf boxes shows that empty BVs are removed.  &#xD;
&#xD;
    leafBoxesLV2 = &#xD;
      Select[VertexList[bvh2[&amp;#034;Tree&amp;#034;]], &#xD;
       VertexOutDegree[bvh2[&amp;#034;Tree&amp;#034;], #] == 0 &amp;amp;];&#xD;
    &#xD;
    Graphics3D[{&#xD;
      Polygon[polyPoints],&#xD;
      {Hue[0, 0, 0, 0], EdgeForm[Black], Cuboid /@ leafBoxesLV2}&#xD;
      }, Boxed -&amp;gt; False]&#xD;
&#xD;
![enter image description here][11]&#xD;
&#xD;
Once  all levels are added, the BVH is finalised by linking each leaf box to its associated polygons.  This does not effect the tree structure as the link association is held seperate.&#xD;
&#xD;
    (*For each outermost subdivision (leaf box), find intersecting polygons.  Link to intersecting box via directed edge.  Append to graph *)&#xD;
    finalizeBVH[BVH_]:=Block[{&#xD;
    (* all leaf boxes for BVH *)&#xD;
    leafBoxes=Select[&#xD;
    VertexList[BVH[&amp;#034;Tree&amp;#034;]],&#xD;
    VertexOutDegree[BVH[&amp;#034;Tree&amp;#034;],#]==0&amp;amp;&#xD;
    ],&#xD;
    (* setup temp association *)&#xD;
    temp=&amp;lt;||&amp;gt;,&#xD;
    (* block varaibles *)&#xD;
    leafPolygons,&#xD;
    leafPolygonsEdges&#xD;
    },&#xD;
    (* For each BVH leaf box *)&#xD;
    Do[&#xD;
    (* 3.1. intersecitng polygons for specified BVH leaf box *)&#xD;
    leafPolygons=Select[&#xD;
    BVH[&amp;#034;PolygonObjects&amp;#034;],&#xD;
    Quiet@intersectTriangleBox[leafBoxes[[i]],#]==True&amp;amp;&#xD;
    ];&#xD;
    (* 3.2. associate each specified BVH leaf box to its intersecting polygon(s) *)&#xD;
    AppendTo[temp,leafBoxes[[i]]-&amp;gt;leafPolygons],&#xD;
    {i,1,Length[leafBoxes],1}&#xD;
    ];&#xD;
    Return[&amp;lt;|&#xD;
    &amp;#034;Tree&amp;#034;-&amp;gt;BVH[&amp;#034;Tree&amp;#034;],&#xD;
    &amp;#034;LeafObjects&amp;#034;-&amp;gt;temp,&#xD;
    &amp;#034;PolygonObjects&amp;#034;-&amp;gt;BVH[&amp;#034;PolygonObjects&amp;#034;]&#xD;
    |&amp;gt;]&#xD;
    ];&#xD;
&#xD;
    bvh2 = finalizeBVH[bvh2];&#xD;
&#xD;
While it only needs doing once, generating the BVH is often the longest part of the procedure so it&amp;#039;s a good idea to export it on completion.&#xD;
&#xD;
&#xD;
Generating The Scene&#xD;
--------------------&#xD;
&#xD;
The scene is an encapsulation of all data and parameters used for the ray caster.  It&amp;#039;s initially structured as: &#xD;
    &#xD;
    scene=&amp;lt;|&#xD;
    &amp;#034;BVH&amp;#034;-&amp;gt;BVHobj,                               -- (*The BVH previously generated*)&#xD;
    &amp;#034;SourcePositions&amp;#034;-&amp;gt;lightingPath,      -- (*The 3D position(s) of the light source*)&#xD;
    &amp;#034;FrameCount&amp;#034;-&amp;gt;frameCount,            -- (*A timestep for animation and a parameter if lightingPath is continuous*)&#xD;
    &amp;#034;Refinement&amp;#034;-&amp;gt;rayRefinement,        -- (*Ray density; smaller values give finer results.*)&#xD;
    &amp;#034;ProjectionPoints&amp;#034;-&amp;gt;planeSpec,       -- (*3D points forming surface(s) that shadow(s) are cast onto.*)&#xD;
    &amp;#034;FrameData&amp;#034;-&amp;gt;&amp;lt;||&amp;gt;                           -- (*Initially empty, data from the ray caster will be stored here.*)&#xD;
    |&amp;gt;&#xD;
&#xD;
&#xD;
Generating The Projection Surface&#xD;
-----------------------------&#xD;
&#xD;
The house should look like its casting it&amp;#039;s shadow onto the earth so we define a list of points which represent the discrete plane it stands on.  Each ray is a line drawn between each point on the projection surface and the position of the scene&amp;#039;s light source.&#xD;
&#xD;
    (* rayRefinement *)&#xD;
    ref = 20;&#xD;
    (* the height of the projection surface *)&#xD;
    planeZoffset = 0;&#xD;
    (* the discrete projection surface - each point is the origin of a \&#xD;
    ray *)&#xD;
    projectionPts = &#xD;
      Catenate[Table[{x, y, planeZoffset}, {x, -900, 1200, ref}, {y, -600,&#xD;
          1000, ref}]];&#xD;
    &#xD;
    Graphics3D[{&#xD;
      Polygon[polyPoints],&#xD;
      Cuboid /@ ({##, ## + {ref, ref, 0}} &amp;amp; /@ projectionPts)&#xD;
      }, Axes -&amp;gt; True, AxesLabel -&amp;gt; {&amp;#034;X&amp;#034;, &amp;#034;Y&amp;#034;, &amp;#034;Z&amp;#034;}, ImageSize -&amp;gt; Large]&#xD;
&#xD;
![enter image description here][12]&#xD;
&#xD;
&#xD;
Specifying A Light Source&#xD;
-------------------------&#xD;
&#xD;
The light source is typically a continuous BSplineFunction which is sampled according to the number of frames the user wants.  But it may also be a discrete list of 3D points too (in which case the number of frames is equal to the length of the list).&#xD;
&#xD;
Using a modification of  a `SunPosition` example in the documentation, a list of the 3D Cartesian positions of the sun between sunrise and sunset, with a time step 30 minutes, is produced.&#xD;
&#xD;
![enter image description here][13]&#xD;
&#xD;
    solarPositionPts0[location_:Here, date_:DateValue[Now,{&amp;#034;Year&amp;#034;,&amp;#034;Month&amp;#034;,&amp;#034;Day&amp;#034;}],tSpec_:{30,&amp;#034;Minute&amp;#034;}]:=&#xD;
    Evaluate[CoordinateTransformData[&amp;#034;Spherical&amp;#034;-&amp;gt;&amp;#034;Cartesian&amp;#034;,&amp;#034;Mapping&amp;#034;,{1,\[Pi]/2-(#2 Degree),2Pi-(#1 Degree)}]]&amp;amp;@@@(Function[{series},Map[QuantityMagnitude,series[&amp;#034;Values&amp;#034;],{2}]]@SunPosition[location,DateRange[Sunrise[#],Sunset[#],tSpec]&amp;amp;[DateObject[date]]])&#xD;
&#xD;
    solarPositionPts[Here, DateObject[{2017, 6, 1}], {30, &amp;#034;Minute&amp;#034;}]&#xD;
    &#xD;
    {{0.4700, -0.88253, -0.0155}, {0.4026, -0.91178, 0.0809},...,{0.4219, 0.90493, 0.0554}}&#xD;
&#xD;
&#xD;
It&amp;#039;s easier to rotate the sun&amp;#039;s path rather than the model and projection plane.  Different transforms may also be applied to best-fit the path into the scene.&#xD;
&#xD;
    solarXoffset = 0;&#xD;
    solarYoffset = 0;&#xD;
    solarZoffset = 0;&#xD;
    zRotation = \[Pi]/3.5;&#xD;
    scale = 1300;&#xD;
    &#xD;
    sourceSpec = &#xD;
      RotationTransform[zRotation, {0, 0, 1}][&#xD;
        # + {solarXoffset, solarYoffset, solarZoffset} &amp;amp; /@ (solarPositionPts[Here, DateObject[{2017, 6, 1}], {30, &amp;#034;Minute&amp;#034;}] scale)&#xD;
      ];&#xD;
    &#xD;
    lightingPath = BSplineCurve[sourceSpec];&#xD;
&#xD;
&#xD;
&#xD;
Specify A Frame Count&#xD;
---------------------&#xD;
&#xD;
A frame count must be specified to discretize the light path into 3D points.  Each of these points forms the end of each ray.&#xD;
If the light source is a discrete list, then its length is used to infer the frame count instead and does not need specifying by the user.&#xD;
&#xD;
    frameCount = 30;&#xD;
&#xD;
&#xD;
Constructing The Scene&#xD;
----------------------&#xD;
&#xD;
Now we can preview the scene&#xD;
&#xD;
    Graphics3D[{&#xD;
      Polygon[polyPoints],&#xD;
      Cuboid /@ ({##, ## + {ref, ref, 0}} &amp;amp; /@ projectionPts),&#xD;
      lightingPath,&#xD;
      {Darker@Yellow, PointSize[0.03], &#xD;
       Point[BSplineFunction[sourceSpec] /@ Range[0, 1, N[1/frameCount]]]}&#xD;
      }, Axes -&amp;gt; True, AxesLabel -&amp;gt; {&amp;#034;X&amp;#034;, &amp;#034;Y&amp;#034;, &amp;#034;Z&amp;#034;}, ImageSize -&amp;gt; Large]&#xD;
&#xD;
![enter image description here][14]&#xD;
&#xD;
 All paramaters have been set, it&amp;#039;s time to construct the scene.  Specifying a continuous lighting path must be done using a `BSPlineCurve`.&#xD;
&#xD;
    scene = newScene[bvh2, lightingPath, frameCount, ref, projectionPts]&#xD;
&#xD;
![enter image description here][15]&#xD;
&#xD;
&#xD;
&#xD;
Processing A Scene For Shadow Mapping&#xD;
-------------------------------------&#xD;
&#xD;
The BVH optimises the ray caster by reducing the number of polygons to search against for an intersection.  If the ray intersects with the BVH root box then a breadth-first search along the BVH tree is initiated.  Starting with the root box,the out-components are selected by their intersection with a ray and are used as roots for the search&amp;#039;s next level.&#xD;
&#xD;
    (* select peripheral out-components of root box that intersect with ray *)&#xD;
    intersectingSubBoxes[BVHObj_,initialVertex_,rayOrigin_,raySource_]:=Select[Rest[VertexOutComponent[BVHObj[&amp;#034;Tree&amp;#034;],{initialVertex},1]],intersectRayBox[#,rayOrigin,raySource]==True&amp;amp;];&#xD;
&#xD;
    (* for root box intersecting rays, find which leaf box(es) intersect with ray *)&#xD;
    BVHLeafBoxIntersection[BVHObj_,rayInt_,rayDest_]:=Block[{v0},&#xD;
    (*initialize search *)v0=intersectingSubBoxes[BVHObj,VertexList[BVHObj[&amp;#034;Tree&amp;#034;]][[1]],rayInt,rayDest];&#xD;
    (* breadth search *)&#xD;
    If[v0=={},Return[v0],&#xD;
    While[&#xD;
    (* check that vertex isn&amp;#039;t a polygon - true if !0.  Check that intersection isn&amp;#039;t empty *)&#xD;
    AllTrue[VertexOutDegree[BVHObj[&amp;#034;Tree&amp;#034;],#]&amp;amp;/@v0,#=!=0&amp;amp;],&#xD;
    v0=Flatten[intersectingSubBoxes[BVHObj,#,rayInt,rayDest]&amp;amp;/@v0,1];&#xD;
    If[v0==={},Break[]]&#xD;
    ];&#xD;
    Return[v0];&#xD;
    ]&#xD;
    ];&#xD;
    &#xD;
&#xD;
The code below generates a visualisation of this process using the input data from the scene generated.&#xD;
&#xD;
    raySource = scene[&amp;#034;ProjectionPoints&amp;#034;][[3700]];&#xD;
    rayDestination = scene[&amp;#034;FrameData&amp;#034;][16][&amp;#034;SourcePosition&amp;#034;];&#xD;
    &#xD;
    lv1Intersection = &#xD;
      BVHLeafBoxIntersection[bvh, raySource, rayDestination];&#xD;
    lv2Intersection = &#xD;
      BVHLeafBoxIntersection[bvh2, raySource, rayDestination];&#xD;
    &#xD;
    lv1Subgraph = &#xD;
      Subgraph[Graph[EdgeList[bvh2[&amp;#034;Tree&amp;#034;]]], &#xD;
       First[VertexList[bvh2[&amp;#034;Tree&amp;#034;]]] \[DirectedEdge] # &amp;amp; /@ &#xD;
        lv1Intersection];&#xD;
    lv2Subgraphs = Subgraph[Graph[EdgeList[bvh2[&amp;#034;Tree&amp;#034;]]], Flatten[Table[&#xD;
         lv1Intersection[[&#xD;
             i]] \[DirectedEdge] # &amp;amp; /@ (Intersection[#, &#xD;
               lv2Intersection] &amp;amp; /@ ((Rest@&#xD;
                  VertexOutComponent[bvh2[&amp;#034;Tree&amp;#034;], #] &amp;amp; /@ &#xD;
                lv1Intersection)))[[i]],&#xD;
         {i, 1, Length[lv1Intersection], 1}&#xD;
         ], 1]];&#xD;
    lbl = ((#[[1]] -&amp;gt; #[[2]]) &amp;amp; /@ (Transpose[{lv2Intersection, &#xD;
           ToString /@ Range[Length[lv2Intersection]]}]));&#xD;
    edgeStyle = Join[&#xD;
       ReleaseHold@&#xD;
        Thread[(# -&amp;gt; HoldForm@{Thick, Blue}) &amp;amp;[EdgeList[lv2Subgraphs]]],&#xD;
       ReleaseHold@&#xD;
        Thread[(# -&amp;gt; HoldForm@{Thick, Red}) &amp;amp;[EdgeList[lv1Subgraph]]]&#xD;
       ];&#xD;
    &#xD;
    rayBVHTraversal = Graph[EdgeList[bvh2[&amp;#034;Tree&amp;#034;]], EdgeStyle -&amp;gt; edgeStyle,&#xD;
       VertexLabels -&amp;gt; lbl,&#xD;
       GraphHighlight -&amp;gt; lv2Intersection,&#xD;
       ImageSize -&amp;gt; Medium];&#xD;
    &#xD;
    rayModelIntersection = Graphics3D[{&#xD;
        {Green, Thickness[0.01], &#xD;
         Line[{raySource, rayDestination - {220, -400, 400}}]},&#xD;
        {Hue[0, 0, 0, 0], EdgeForm[{Thick, Red}], &#xD;
         Cuboid /@ lv1Intersection},&#xD;
        {Hue[.6, 1, 1, .3], EdgeForm[{Thick, Blue}], &#xD;
         Cuboid /@ lv2Intersection},&#xD;
        {Opacity[0.5], Polygon[polyPoints]},&#xD;
        Inset @@@ &#xD;
         Transpose[{ToString /@ Range[Length[lv2Intersection]], &#xD;
           RegionCentroid /@ Cuboid @@@ lv2Intersection}]&#xD;
        }];&#xD;
    &#xD;
    Column[{&#xD;
      Row[&#xD;
       Show[rayModelIntersection, ViewPoint -&amp;gt; #, Boxed -&amp;gt; False, &#xD;
          ImageSize -&amp;gt; Medium] &amp;amp; /@ {{-\[Infinity], 0, &#xD;
          0}, {0, -\[Infinity], 0}}&#xD;
       ],&#xD;
      rayBVHTraversal&#xD;
      }]&#xD;
&#xD;
![enter image description here][17]&#xD;
&#xD;
At the centre of the graph lies the vertex representing the root BV where all searches originate from.  The search continues out form all vertices which have intersected with the ray.&#xD;
&#xD;
&#xD;
    (* test intersection between ray and object polygon via BVH search *)&#xD;
    intersectionRayBVH[BVHObj_,rayOrigin_,rayDest_]:=With[{&#xD;
    intersectionLeafBoxes=BVHLeafBoxIntersection[BVHObj,rayOrigin,rayDest]&#xD;
    },&#xD;
    Block[{i},If[intersectionLeafBoxes=!={},&#xD;
    Return[Catch[For[i=1,i&amp;lt;Length[#],i++,&#xD;
    Function[{thowQ},If[thowQ,Throw[thowQ]]][intersectRayTriangle[#[[1]],#[[2]],#[[3]],rayOrigin,rayDest]&amp;amp;@#[[i]]]&#xD;
    ]&amp;amp;[DeleteDuplicates[Flatten[Lookup[BVHObj[&amp;#034;LeafObjects&amp;#034;],intersectionLeafBoxes],1]]]]===True],&#xD;
    Return[False]&#xD;
    ]]&#xD;
    ];&#xD;
&#xD;
Once the tree has been fully searched, the remaining boxes are used to lookup their associated polygons.  Since the same polygon may intersect more than one box, any duplicates are deleted.  A line-triangle intersection test is iteratively applied over the resultant list, breaking at the first instance of a True return.  This ray has now been found to intersect a part of the 3D model thus its origin point (from the `projectionPts` list) will represent a single point of shadow on the projection surface.  This point is stored in a list which will be used to draw the shadow for a single frame.  &#xD;
&#xD;
    candidatePolys = DeleteDuplicates[Flatten[Lookup[&#xD;
         bvh2[&amp;#034;LeafObjects&amp;#034;],&#xD;
         BVHLeafBoxIntersection[bvh2, raySource, rayDestination]&#xD;
         ], 1]];&#xD;
    &#xD;
    intersectingPolys = &#xD;
      Select[candidatePolys,PrimitiveIntersectionQ3D[Line[{raySource, rayDestination}],Triangle[#]] &amp;amp;];&#xD;
    &#xD;
    rayModelIntersectionPolys = Graphics3D[{&#xD;
        {Green, Thickness[0.01], &#xD;
         Line[{raySource, rayDestination - {220, -400, 400}}]},&#xD;
        {Hue[1, 1, 1, .5], EdgeForm[Black], Polygon[candidatePolys]},&#xD;
        {Hue[0.3, 1, 1, .5], Polygon[intersectingPolys]}&#xD;
        }, Boxed -&amp;gt; False];&#xD;
    &#xD;
    Row[Show[rayModelIntersectionPolys, ViewPoint -&amp;gt; #, ImageSize -&amp;gt; Medium] &amp;amp; /@ {{0, 0, \[Infinity]}, {0, \[Infinity], 0}}]&#xD;
&#xD;
Highlighted in green, the ray has been found to intersect with 2 polygons.&#xD;
&#xD;
![enter image description here][18]&#xD;
&#xD;
The BVH search is performed for each ray, for each frame.&#xD;
&#xD;
A scene is the input for the ray caster.  If a scene is to be re-processed with different parameters then a new scene must be made.&#xD;
The output of the ray caster is held within a scene object.  The data for each frame is associated to its frame index and is all held in the scene&amp;#039;s &amp;#034;FrameData&amp;#034; field.&#xD;
&#xD;
Begin processing.  A status bar will indicate progress in terms of frames rendered.&#xD;
&#xD;
    scene = renderScene[scene];&#xD;
&#xD;
it&amp;#039;s best to save any progress by exporting afterwards.&#xD;
&#xD;
    Export[&amp;#034;House_scene.txt&amp;#034;, Compress[scene]]&#xD;
&#xD;
&#xD;
Reviewing Processed Scenes&#xD;
--------------------------&#xD;
&#xD;
Each frame holds the shadow and ground data separately and have been expressed as zero-thickness cuboids (tiles) and each with side length equal to the `rayRefinement` parameter (recall that smaller values yield finer results).&#xD;
&#xD;
Individual frames are accessed by their frame index.  This examines frame 10.&#xD;
&#xD;
    Keys[scene[&amp;#034;FrameData&amp;#034;][10]]&#xD;
    &#xD;
    {&amp;#034;ShadowPts&amp;#034;, &amp;#034;SourcePosition&amp;#034;, &amp;#034;GroundPts&amp;#034;}&#xD;
&#xD;
&#xD;
Accessing the processed scene&amp;#039;s &amp;#034;FrameData&amp;#034; field allows a single specified frame to be drawn in Graphics3D.&#xD;
&#xD;
    Graphics3D[{&#xD;
      Polygon[scene[&amp;#034;BVH&amp;#034;][&amp;#034;PolygonObjects&amp;#034;]],&#xD;
      {GrayLevel[0.3], EdgeForm[], &#xD;
       Cuboid /@ scene[&amp;#034;FrameData&amp;#034;][10][&amp;#034;ShadowPts&amp;#034;]},&#xD;
      {EdgeForm[], Cuboid /@ scene[&amp;#034;FrameData&amp;#034;][10][&amp;#034;GroundPts&amp;#034;]},&#xD;
      {Darker@Yellow, PointSize[0.04], &#xD;
       Point[scene[&amp;#034;FrameData&amp;#034;][10][&amp;#034;SourcePosition&amp;#034;]]}&#xD;
      }, Boxed -&amp;gt; False, Background -&amp;gt; LightBlue]&#xD;
&#xD;
![enter image description here][23]&#xD;
&#xD;
&#xD;
`viewSceneFrame` does the task above for any processed scene and specified frame.  It inherits Graphics3D options as well as custom ones affecting the scene elements (shadow and ground style, toggle source drawing and gridlines).&#xD;
&#xD;
    viewSceneFrame[scene, 10, DrawGrid -&amp;gt; False, ShadowColor -&amp;gt; GrayLevel[0.3], SurfaceColor -&amp;gt; Lighter@Orange,  DrawSource -&amp;gt; True, Boxed -&amp;gt; False, Background -&amp;gt; LightBlue]&#xD;
&#xD;
![enter image description here][24]&#xD;
&#xD;
    Show[viewSceneFrame[scene, 10, DrawGrid -&amp;gt; False, &#xD;
      ShadowColor -&amp;gt; GrayLevel[0.3], SurfaceColor -&amp;gt; Lighter@Orange, &#xD;
      DrawSource -&amp;gt; True, Boxed -&amp;gt; False, Background -&amp;gt; LightBlue], &#xD;
     ViewPoint -&amp;gt; {0, 0, \[Infinity]}]&#xD;
&#xD;
![enter image description here][25]&#xD;
&#xD;
&#xD;
    sceneBounds = Join[&#xD;
       Most[MinMax /@ Transpose[scene[&amp;#034;ProjectionPoints&amp;#034;]]],&#xD;
       {MinMax[&#xD;
         Last /@ Values[scene[&amp;#034;FrameData&amp;#034;][[All, &amp;#034;SourcePosition&amp;#034;]]]]}&#xD;
       ];&#xD;
    viewSceneFrame[scene, 10, DrawGrid -&amp;gt; False, &#xD;
     ShadowColor -&amp;gt; GrayLevel[0.3], SurfaceColor -&amp;gt; Lighter@Orange, &#xD;
     DrawSource -&amp;gt; True, Boxed -&amp;gt; False, Background -&amp;gt; LightBlue, &#xD;
     Axes -&amp;gt; True, AxesLabel -&amp;gt; {&amp;#034;X&amp;#034;, &amp;#034;Y&amp;#034;, &amp;#034;Z&amp;#034;}, PlotRange -&amp;gt; sceneBounds]&#xD;
&#xD;
![enter image description here][26]&#xD;
&#xD;
&#xD;
Retaining the same options, the scene may also be animated.  To ensure a smooth playback, each frame is exported as .gif into `$TemporaryDirectory`, imported back as a list and animated.  The animation is also exported for future use.&#xD;
&#xD;
    animateScene[scene,&#xD;
     DrawGrid -&amp;gt; False,&#xD;
     ShadowColor -&amp;gt; GrayLevel[0.3],&#xD;
     SurfaceColor -&amp;gt; Lighter@Orange,&#xD;
     DrawSource -&amp;gt; True,&#xD;
     Boxed -&amp;gt; False,&#xD;
     Background -&amp;gt; LightBlue,&#xD;
     PlotRange -&amp;gt; sceneBounds,&#xD;
     ImageSize -&amp;gt; {{800}, {600}}&#xD;
     ]&#xD;
&#xD;
![enter image description here][27]&#xD;
&#xD;
&#xD;
We can also plot the cumulative solar exposure.&#xD;
&#xD;
All points from the projection plane which don&amp;#039;t intersect with the model (i.e, aren&amp;#039;t shadow points) are extracted from the scene&amp;#039;s frames&#xD;
&#xD;
    exposure = Values[scene[&amp;#034;FrameData&amp;#034;][[All, &amp;#034;GroundPts&amp;#034;]]]&#xD;
&#xD;
![enter image description here][28]&#xD;
&#xD;
&#xD;
&#xD;
The occurrences of each exposure point is tallied&#xD;
&#xD;
    tally = Tally[Flatten[exposure, 1]]&#xD;
&#xD;
![enter image description here][29]&#xD;
&#xD;
&#xD;
And the range of frequencies from which is generated&#xD;
&#xD;
    tallyRange = &#xD;
     Range @@ Insert[MinMax[Last /@ SortBy[tally, Last]], 1, -1]&#xD;
    &#xD;
    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, \&#xD;
    20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}&#xD;
&#xD;
&#xD;
A color scale corresponding to the range of frequencies from above will be used to colorize the plot&#xD;
&#xD;
    colorScale = &#xD;
     ColorData[&amp;#034;SolarColors&amp;#034;, &amp;#034;ColorFunction&amp;#034;] /@ Rescale[tallyRange]&#xD;
&#xD;
![enter image description here][30]&#xD;
&#xD;
&#xD;
Replacement rules are used to replace each exposure point&amp;#039;s frequency with it&amp;#039;s corresponding color&#xD;
&#xD;
    colorScaleRules = Thread @@ {tallyRange -&amp;gt; colorScale}&#xD;
&#xD;
![enter image description here][31]&#xD;
&#xD;
&#xD;
The resultant exposure map is a list of tiles, each coloured according to it&amp;#039;s positional frequency.&#xD;
&#xD;
    heatMap = &#xD;
     Insert[MapAt[Cuboid, &#xD;
         Reverse@MapAt[Replace[colorScaleRules], #, -1], -1], EdgeForm[], &#xD;
        2] &amp;amp; /@ tally&#xD;
&#xD;
![enter image description here][32]&#xD;
&#xD;
Finally, the map is drawn.  It&amp;#039;s still a `Graphics3D` object so it may be rotated and viewed from any angle.&#xD;
&#xD;
    Row[{&#xD;
      Show[Graphics3D[{&#xD;
         {Opacity[0.3], Green, Polygon[scene[&amp;#034;BVH&amp;#034;][&amp;#034;PolygonObjects&amp;#034;]]},&#xD;
         heatMap&#xD;
         }, Boxed -&amp;gt; False, ImageSize -&amp;gt; Large], ViewPoint -&amp;gt; Above],&#xD;
      BarLegend[{&amp;#034;SolarColors&amp;#034;, MinMax[tallyRange]}]&#xD;
      }]&#xD;
&#xD;
![enter image description here][33]&#xD;
&#xD;
The process of generating an exposure map forms a function within the `GeometricIntersections3D` package.  &#xD;
Alternative color schemes may also be specified.&#xD;
&#xD;
    sceneExposureMap[scene, &amp;#034;TemperatureMap&amp;#034;]&#xD;
&#xD;
![enter image description here][34]&#xD;
&#xD;
&#xD;
The bar scale for the exposure plot measures duration in frames but a time scale may be recovered.&#xD;
Given that the solar path used to light the scene lasts about 14 hours and the scene was rendered for 30 frames, that gives about 30 minutes per frame.&#xD;
&#xD;
    dailySunHours = &#xD;
     UnitConvert[DateDifference[Sunrise[], Sunset[]], &#xD;
      MixedRadix[&amp;#034;Hours&amp;#034;, &amp;#034;Minutes&amp;#034;, &amp;#034;Seconds&amp;#034;]]&#xD;
&#xD;
![enter image description here][35]&#xD;
&#xD;
&#xD;
    dailySunHours/30&#xD;
&#xD;
![enter image description here][36]&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
This has been a very rewarding project with some exciting potentials beyond computer graphics.  Indeed, much optimisations can be made to the intersections package.  &#xD;
The different methods of space partitioning for BVH construction should be investigated as the one currently employed is rather rudimentary.&#xD;
Anti-aliasing methods to be investigated also.&#xD;
&#xD;
Both the House and Sundial processes are documented in the notebooks attached.  All necessary data may also be downloaded to save time.&#xD;
&#xD;
&#xD;
&#xD;
&#xD;
 &#xD;
&#xD;
&#xD;
  [1]: https://en.wikipedia.org/wiki/Shadow_mapping&#xD;
  [2]: http://community.wolfram.com//c/portal/getImageAttachment?filename=animation.gif&amp;amp;userId=605083&#xD;
  [3]: https://3dwarehouse.sketchup.com/&#xD;
  [4]: https://github.com/b-goodman/GeometricIntersections3D&#xD;
  [5]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_Import.png&amp;amp;userId=605083&#xD;
  [6]: https://en.wikipedia.org/wiki/Bounding_volume_hierarchy&#xD;
  [7]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_TreeLV1.png&amp;amp;userId=605083&#xD;
  [8]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_leafBoxesLV1.png&amp;amp;userId=605083&#xD;
  [9]: http://community.wolfram.com//c/portal/getImageAttachment?filename=cuboidSubdivide.gif&amp;amp;userId=605083&#xD;
  [10]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_TreeLV2.png&amp;amp;userId=605083&#xD;
  [11]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_leafBoxesLV2.png&amp;amp;userId=605083&#xD;
  [12]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_projectionPoints.png&amp;amp;userId=605083&#xD;
  [13]: http://community.wolfram.com//c/portal/getImageAttachment?filename=solarPosition.PNG&amp;amp;userId=605083&#xD;
  [14]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_scenePreview.png&amp;amp;userId=605083&#xD;
  [15]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_sceneConstructor.png&amp;amp;userId=605083&#xD;
  [16]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_projectionPoints.png&amp;amp;userId=605083&#xD;
  [17]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_raySearch.png&amp;amp;userId=605083&#xD;
  [18]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_rayIntersection.png&amp;amp;userId=605083&#xD;
  [19]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_projectionPoints.png&amp;amp;userId=605083&#xD;
  [20]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_projectionPoints.png&amp;amp;userId=605083&#xD;
  [21]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_projectionPoints.png&amp;amp;userId=605083&#xD;
  [22]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_projectionPoints.png&amp;amp;userId=605083&#xD;
  [23]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_singleFrame_1.png&amp;amp;userId=605083&#xD;
  [24]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_singleFrame_2.png&amp;amp;userId=605083&#xD;
  [25]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_singleFrame_3.png&amp;amp;userId=605083&#xD;
  [26]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_singleFrame_4.png&amp;amp;userId=605083&#xD;
  [27]: http://community.wolfram.com//c/portal/getImageAttachment?filename=animation_House.gif&amp;amp;userId=605083&#xD;
  [28]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_exposureStep_A.png&amp;amp;userId=605083&#xD;
  [29]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_exposureStep_B.png&amp;amp;userId=605083&#xD;
  [30]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_exposureStep_C.png&amp;amp;userId=605083&#xD;
  [31]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_exposureStep_D.png&amp;amp;userId=605083&#xD;
  [32]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_exposureStep_E.png&amp;amp;userId=605083&#xD;
  [33]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_solarMap_A.png&amp;amp;userId=605083&#xD;
  [34]: http://community.wolfram.com//c/portal/getImageAttachment?filename=Process_House_solarMap_B.png&amp;amp;userId=605083&#xD;
  [35]: http://community.wolfram.com//c/portal/getImageAttachment?filename=sunHours.png&amp;amp;userId=605083&#xD;
  [36]: http://community.wolfram.com//c/portal/getImageAttachment?filename=sunHoursPerFrame.png&amp;amp;userId=605083</description>
    <dc:creator>Benjamin Goodman</dc:creator>
    <dc:date>2017-06-01T07:01:10Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/802316">
    <title>Announcing: The Wolfram Community Ambassador Program</title>
    <link>https://community.wolfram.com/groups/-/m/t/802316</link>
    <description>Just last spring, we began the process of hand-picking the best and brightest U.S College&#xD;
students to represent us as Wolfram Student Ambassadors. We wanted to see what we could create if&#xD;
we gave those with a pre-existing passion for all-things-Wolfram the resources and support to do what&#xD;
many of them were already doing by their own accord  introducing their peers to the Wolfram&#xD;
Technology stack, and showing them first-hand its accessibility. Over the past year, its been fascinating&#xD;
to see how many different academic disciplines yield enthusiastic and talented applicants. More&#xD;
fascinating yet, were the applicants that defied our original demographic parameters: our *Student*&#xD;
Ambassador Program was receiving applications from *professors*, and even people without any&#xD;
academic affiliation at all. Which made sense  while Wolfram software has had a steady, growing&#xD;
popularity amongst students in recent years, its most loyal fans have been users since Mathematicas&#xD;
conception in the late 80s. Knowing this, coupled with the positive precedent set by the success of our Student&#xD;
Ambassador Program, it became apparent we needed to create a new program - something especially&#xD;
designed for our original Ambassadors.&#xD;
&#xD;
So who are we looking for?&#xD;
&#xD;
Odds are, youve been with us since the beginning. Youre most likely a natural leader, and love to get&#xD;
your friends/colleagues/students to that light bulb moment on projects and collaborations. Or maybe&#xD;
youre an especially active member on community.wolfram.com, and you excel at performing solo&#xD;
projects with our software. Whatever it may be, we want to empower you to be able to do even more&#xD;
of it. This program will offer support to our professional enthusiasts, and give us the opportunity to say&#xD;
thank you by providing complimentary benefits, support, and tools for establishing a community or&#xD;
developing a personal project. Wed like to encourage anyone who has either considered or possibly&#xD;
already created a group to contact us in order to discuss getting involved in this new partnership&#xD;
opportunity.&#xD;
&#xD;
Benefits, which will vary in accordance to background/ area of expertise, may include:&#xD;
&#xD;
&#xD;
----------&#xD;
&#xD;
&#xD;
 - Free Access to select Wolfram technologies&#xD;
 - Cloud Credits (up to 1,000,000)&#xD;
 - Training and workshop access&#xD;
 - Materials and marketing merchandise for meetups/workshops&#xD;
 - Opportunity for professional development as you give talks, organize meetups, and inspire others&#xD;
 - Potential publication opportunities through Wolfram Media&#xD;
 &#xD;
&#xD;
Weve provided the platform  now were passing you the baton. This is our chance to thank you for the&#xD;
help youve already provided us, and support you as you help nurture and inspire the next&#xD;
generation of Wolfram Users.&#xD;
&#xD;
If you would like to know more, contact us at wca@wolfram.com</description>
    <dc:creator>Samantha Newman</dc:creator>
    <dc:date>2016-02-24T23:29:52Z</dc:date>
  </item>
</rdf:RDF>

