<?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 High-Performance Computing sorted by most likes.</description>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1085633" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/2542490" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/3067969" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/2763509" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/3022104" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/96823" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/3024465" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/2434669" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1057588" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/2516662" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/3082695" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/3725603" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/2961701" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/2416125" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/2429964" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/3062083" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/2932299" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/2510803" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/2472460" />
        <rdf:li rdf:resource="https://community.wolfram.com/groups/-/m/t/1927307" />
      </rdf:Seq>
    </items>
  </channel>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1085633">
    <title>How-To-Guide: External GPU on OSX - how to use CUDA on your Mac</title>
    <link>https://community.wolfram.com/groups/-/m/t/1085633</link>
    <description>The neural network and machine learning framework has become one of the key features of the latest releases of the Wolfram Language. Training neural networks can be very time consuming on a standard CPU. Luckily the Wolfram Language offers an incredible easy way to use a GPU to train networks - and do lots of other cool stuff. The problem with this was/is that most current Macs do not have an NVIDIA graphics card, which is necessary to access this framework within the Wolfram Language. Therefore, Wolfram Inc. had decided to drop support for GPUs on Macs. There is however a way to use GPUs on Macs. For example you can use an [external GPU like the one offered by Bizon][1]. &#xD;
&#xD;
![enter image description here][2]&#xD;
&#xD;
Apart from the BizonBox there a couple of cables and a power supply. You can buy/configure different versions of the BizonBox: there is a range of different graphics cards available and you can buy a the BizonBox 2s which basically connects via Thunderbolt and the BizonBox 3 which connects to USB-C. &#xD;
&#xD;
Luckily, Wolfram have decided to reintroduce support for GPUs in Mathematica 11.1.1 - see [the discussion here][3]. &#xD;
&#xD;
 I have a variety of these BizonBoxes (both 2s and 3) and a range of Macs. I thought it would be a good idea to post a how-to. The essence of what I will be describing in this post should work for most Macs. I ran Sierra on all of them. Here is the recipe to get the thing to work:&#xD;
&#xD;
Installation of the BizonBox, the required drivers, and compilers&#xD;
-----------------------------------------------------------------&#xD;
&#xD;
0. I will assume that you have Sierra installed and that Xcode is running. One of the really important steps if you want to use compilers is to ***downgrade*** the command line tools to version 7.3 You will  have to log into your Apple Developer account and download the Command Line Tools version 7.3. Install the tools and run the  terminal command (not in Mathematica!): &#xD;
&#xD;
        sudo xcode-select  --switch /Library/Developer/CommandLineTools&#xD;
&#xD;
1. Reboot your Mac into safe mode, i.e. hold CMD+R while rebooting. &#xD;
&#xD;
2. Open a terminal (under item Utilities at the top of the screen).&#xD;
&#xD;
3. Enter &#xD;
&#xD;
        csrutil disable &#xD;
&#xD;
4. Shut the computer down.&#xD;
&#xD;
5. Connect your BizonBox to the mains and to either the thunderbolt or USB-C port of your Mac.&#xD;
&#xD;
6. Restart your Mac. &#xD;
&#xD;
7. Click on the Apple symbol in the top left. Then &amp;#034;About this Mac&amp;#034; and &amp;#034;System Report&amp;#034;. In the Thunderbolt section you should see something like this:&#xD;
&#xD;
![enter image description here][4]&#xD;
&#xD;
8. In the documentation of the BizonBox you will find a link to a program called bizonboxmac.zip. Download that file and unzip it.&#xD;
&#xD;
9. Open the folder and click on &amp;#034;bizonbox.prefPane&amp;#034; to install. (If prompted to, do update!)&#xD;
&#xD;
10. You should see this window:&#xD;
&#xD;
![enter image description here][6]&#xD;
&#xD;
11. Click on Activate. Type in password if required to do so. It should give something like this:&#xD;
&#xD;
![enter image description here][7]&#xD;
&#xD;
Then restart.&#xD;
&#xD;
12.  Install the CUDA Toolkit: [https://developer.nvidia.com/cuda-downloads][8]. You&amp;#039;ll have to click through some questions for the download. &#xD;
&#xD;
![enter image description here][9]&#xD;
&#xD;
what you download should be something like cuda_8.0.61_mac.dmg and it should be more or less 1.44 GB worth. &#xD;
&#xD;
13.  Install the toolkit with all its elements.&#xD;
&#xD;
![enter image description here][10]&#xD;
&#xD;
14. Restart your computer.&#xD;
&#xD;
First tests&#xD;
-----------&#xD;
&#xD;
Now you should be good to go. Open Mathematica 11.1.1. Execute &#xD;
&#xD;
    Needs[&amp;#034;CUDALink`&amp;#034;]&#xD;
    Needs[&amp;#034;CCompilerDriver`&amp;#034;]&#xD;
    CUDAResourcesInstall[]&#xD;
&#xD;
Then try:&#xD;
&#xD;
    CUDAResourcesInformation[]&#xD;
&#xD;
which should look somewhat like this:&#xD;
&#xD;
![enter image description here][11]&#xD;
&#xD;
 Then you should check &#xD;
&#xD;
    SystemInformation[]&#xD;
&#xD;
Head to Links and then CUDA.This should look similar to this:&#xD;
&#xD;
![enter image description here][12]&#xD;
&#xD;
So far so good. Next is the really crucial thing:&#xD;
&#xD;
    CUDAQ[]&#xD;
&#xD;
should give TRUE. If that&amp;#039;s what you see you are good to go. Be more daring and try&#xD;
&#xD;
    CUDAImageConvolve[ExampleData[{&amp;#034;TestImage&amp;#034;,&amp;#034;Lena&amp;#034;}], N[BoxMatrix[1]/9]] // AbsoluteTiming&#xD;
&#xD;
![enter image description here][13]&#xD;
&#xD;
You might notice that the non-GPU version of this command runs faster:&#xD;
&#xD;
    ImageConvolve[ExampleData[{&amp;#034;TestImage&amp;#034;,&amp;#034;Lena&amp;#034;}], N[BoxMatrix[1]/9]] // AbsoluteTiming&#xD;
&#xD;
runs in something like 0.0824 seconds, but that&amp;#039;s ok. &#xD;
&#xD;
Benchmarking (training neural networks)&#xD;
---------------------------------------&#xD;
&#xD;
Let&amp;#039;s do some Benchmarking. Download some example data:&#xD;
&#xD;
    obj = ResourceObject[&amp;#034;CIFAR-10&amp;#034;]; &#xD;
    trainingData = ResourceData[obj, &amp;#034;TrainingData&amp;#034;]; &#xD;
    RandomSample[trainingData, 5]&#xD;
&#xD;
You can check whether it worked:&#xD;
&#xD;
    RandomSample[trainingData, 5]&#xD;
&#xD;
should give something like this:&#xD;
&#xD;
![enter image description here][14]&#xD;
&#xD;
These are the classes of the 50000 images:&#xD;
&#xD;
    classes = Union@Values[trainingData] &#xD;
&#xD;
![enter image description here][15]&#xD;
&#xD;
Let&amp;#039;s build a network &#xD;
&#xD;
    module = NetChain[{ConvolutionLayer[100, {3, 3}], &#xD;
       BatchNormalizationLayer[], ElementwiseLayer[Ramp], &#xD;
       PoolingLayer[{3, 3}, &amp;#034;PaddingSize&amp;#034; -&amp;gt; 1]}]&#xD;
    &#xD;
    net = NetChain[{module, module, module, module, FlattenLayer[], 500, &#xD;
       Ramp, 10, SoftmaxLayer[]}, &#xD;
      &amp;#034;Input&amp;#034; -&amp;gt; NetEncoder[{&amp;#034;Image&amp;#034;, {32, 32}}], &#xD;
      &amp;#034;Output&amp;#034; -&amp;gt; NetDecoder[{&amp;#034;Class&amp;#034;, classes}]]&#xD;
&#xD;
When you train the network:&#xD;
&#xD;
    {time, trained} = AbsoluteTiming@NetTrain[net, trainingData, Automatic, &amp;#034;TargetDevice&amp;#034; -&amp;gt; &amp;#034;GPU&amp;#034;];&#xD;
&#xD;
you should see something like this:&#xD;
&#xD;
![enter image description here][16]&#xD;
&#xD;
So the thing started 45 secs ago and it supposed to finish in 2m54s. In fact, it finished after 3m30s. If we run the same on the CPU we get:&#xD;
&#xD;
![enter image description here][17]&#xD;
&#xD;
The estimate kept changing a bit, but it settled down at about 18h20m.That is slower by a factor of about 315, which is quite substantial. &#xD;
&#xD;
Use of compiler&#xD;
---------------&#xD;
&#xD;
Up to now we have not needed the actual compiler. Let&amp;#039;s try this, too. Let&amp;#039;s grow a Mandelbulb:&#xD;
&#xD;
    width = 4*640;&#xD;
    height = 4*480;&#xD;
    iconfig = {width, height, 1, 0, 1, 6};&#xD;
    config = {0.001, 0.0, 0.0, 0.0, 8.0, 15.0, 10.0, 5.0};&#xD;
    camera = {{2.0, 2.0, 2.0}, {0.0, 0.0, 0.0}};&#xD;
    AppendTo[camera, Normalize[camera[[2]] - camera[[1]]]];&#xD;
    AppendTo[camera, &#xD;
      0.75*Normalize[Cross[camera[[3]], {0.0, 1.0, 0.0}]]];&#xD;
    AppendTo[camera, 0.75*Normalize[Cross[camera[[4]], camera[[3]]]]];&#xD;
    config = Join[{config, Flatten[camera]}];&#xD;
    &#xD;
    pixelsMem = CUDAMemoryAllocate[&amp;#034;Float&amp;#034;, {height, width, 3}]&#xD;
    &#xD;
    srcf = FileNameJoin[{$CUDALinkPath, &amp;#034;SupportFiles&amp;#034;, &amp;#034;mandelbulb.cu&amp;#034;}]&#xD;
&#xD;
Now this should work:&#xD;
&#xD;
    mandelbulb = &#xD;
    CUDAFunctionLoad[File[srcf], &amp;#034;MandelbulbGPU&amp;#034;, {{&amp;#034;Float&amp;#034;, _, &amp;#034;Output&amp;#034;}, {&amp;#034;Float&amp;#034;, _, &amp;#034;Input&amp;#034;}, {&amp;#034;Integer32&amp;#034;, _, &amp;#034;Input&amp;#034;}, &amp;#034;Integer32&amp;#034;, &amp;#034;Float&amp;#034;, &amp;#034;Float&amp;#034;}, {16}, &amp;#034;UnmangleCode&amp;#034; -&amp;gt; False, &amp;#034;CompileOptions&amp;#034; -&amp;gt; &amp;#034;--Wno-deprecated-gpu-targets &amp;#034;, &amp;#034;ShellOutputFunction&amp;#034; -&amp;gt; Print]&#xD;
&#xD;
Under certain circumstances you might want to specify the location of the compiler like so:&#xD;
&#xD;
    mandelbulb = &#xD;
     CUDAFunctionLoad[File[srcf], &amp;#034;MandelbulbGPU&amp;#034;, {{&amp;#034;Float&amp;#034;, _, &amp;#034;Output&amp;#034;}, {&amp;#034;Float&amp;#034;, _, &amp;#034;Input&amp;#034;}, {&amp;#034;Integer32&amp;#034;, _, &amp;#034;Input&amp;#034;}, &amp;#034;Integer32&amp;#034;, &amp;#034;Float&amp;#034;, &#xD;
    &amp;#034;Float&amp;#034;}, {16}, &amp;#034;UnmangleCode&amp;#034; -&amp;gt; False, &amp;#034;CompileOptions&amp;#034; -&amp;gt; &amp;#034;--Wno-deprecated-gpu-targets &amp;#034;, &amp;#034;ShellOutputFunction&amp;#034; -&amp;gt; Print, &#xD;
    &amp;#034;CompilerInstallation&amp;#034; -&amp;gt; &amp;#034;/Developer/NVIDIA/CUDA-8.0/bin/&amp;#034;]&#xD;
&#xD;
This should give:&#xD;
&#xD;
![enter image description here][18]&#xD;
&#xD;
Now&#xD;
&#xD;
    mandelbulb[pixelsMem, Flatten[config], iconfig, 0, 0.0, 0.0, {width*height*3}];&#xD;
    pixels = CUDAMemoryGet[pixelsMem];&#xD;
    Image[pixels]&#xD;
&#xD;
gives&#xD;
&#xD;
![enter image description here][19]&#xD;
&#xD;
So it appears that all is working fine.&#xD;
&#xD;
Problems&#xD;
--------&#xD;
&#xD;
I did come up with some problems though. There is quite a number of CUDA functions:&#xD;
&#xD;
    Names[&amp;#034;CUDALink`*&amp;#034;]&#xD;
&#xD;
![enter image description here][20]&#xD;
&#xD;
Many work just fine. &#xD;
&#xD;
    res = RandomReal[1, 5000];&#xD;
    ListLinePlot[res]&#xD;
&#xD;
![enter image description here][21]&#xD;
&#xD;
    ListLinePlot[First@CUDAImageConvolve[{res}, {GaussianMatrix[{{10}, 10}]}]]&#xD;
&#xD;
![enter image description here][22]&#xD;
&#xD;
The thing is that some don&amp;#039;t and I am not sure why (I have a hypothesis though). Here are some functions that do **not** appear to work:&#xD;
&#xD;
CUDAColorNegate&#xD;
CUDAClamp&#xD;
CUDAFold&#xD;
CUDAVolumetricRender&#xD;
CUDAFluidDynamics&#xD;
&#xD;
and some more. I would be very grateful if someone could check these on OSX (and perhaps Windows?). I am not sure if the this is due to some particularity of my systems or something that could be flagged up to Wolfram Inc for checking.  &#xD;
&#xD;
 When I wanted to try that systematically I wanted to use the function&#xD;
&#xD;
    WolframLanguageData&#xD;
&#xD;
to look for the first example in the documentation of the CUDA functions, but it appears that no CUDA function is in the WolframLanguageData. I think tit would be great to have them there, too, and am not sure why they wouldn&amp;#039;t be there. &#xD;
&#xD;
In spite of these problems I hope that this post will help some Mac users to get CUDA going. It is a great framework and simple to use in the Wolfram Language. With the BizonBox and Mathematica 11.1.1 Mac users are no  longer excluded from accessing this feature. &#xD;
&#xD;
Cheers,&#xD;
&#xD;
Marco&#xD;
&#xD;
PS: Note, that there is anecdotal evidence that one can even use the BizonBox under Windows running in a virtual box under OSX. I don&amp;#039;t have Windows, but I&amp;#039;d like to hear if anyone get this running. &#xD;
&#xD;
  [1]: https://bizon-tech.com&#xD;
  [2]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2017-05-07at22.09.10.png&amp;amp;userId=48754&#xD;
  [3]: http://community.wolfram.com/groups/-/m/t/902394&#xD;
  [4]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot1.png&amp;amp;userId=48754&#xD;
  [5]: http://bizon-tech.com/bizonboxmac.zip&#xD;
  [6]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2.png&amp;amp;userId=48754&#xD;
  [7]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot3.png&amp;amp;userId=48754&#xD;
  [8]: https://developer.nvidia.com/cuda-downloads&#xD;
  [9]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot6.png&amp;amp;userId=48754&#xD;
  [10]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot7.png&amp;amp;userId=48754&#xD;
  [11]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2017-05-07at22.38.22.png&amp;amp;userId=48754&#xD;
  [12]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2017-05-06at18.46.46.png&amp;amp;userId=48754&#xD;
  [13]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2017-05-07at22.49.15.png&amp;amp;userId=48754&#xD;
  [14]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2017-05-07at22.52.43.png&amp;amp;userId=48754&#xD;
  [15]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2017-05-07at22.53.30.png&amp;amp;userId=48754&#xD;
  [16]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2017-05-07at20.37.20.png&amp;amp;userId=48754&#xD;
  [17]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2017-05-07at20.39.02.png&amp;amp;userId=48754&#xD;
  [18]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2017-05-07at23.04.38.png&amp;amp;userId=48754&#xD;
  [19]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2017-05-07at21.50.42.png&amp;amp;userId=48754&#xD;
  [20]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2017-05-07at23.10.05.png&amp;amp;userId=48754&#xD;
  [21]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2017-05-07at23.15.59.png&amp;amp;userId=48754&#xD;
  [22]: http://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2017-05-07at23.16.36.png&amp;amp;userId=48754</description>
    <dc:creator>Marco Thiel</dc:creator>
    <dc:date>2017-05-07T22:21:42Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/2542490">
    <title>Imaging a rotating disk with a rolling shutter</title>
    <link>https://community.wolfram.com/groups/-/m/t/2542490</link>
    <description>![enter image description here][1]&#xD;
&#xD;
The excellent [community contribution][2] by [@Greg Hurst][at0] and a Wikipedia [animation][3], Inspired me to look further into this &amp;#034;rolling shutter effect on rotating objects&amp;#034;. &#xD;
When we capture a video of a rotating disk with a rolling shutter, we have two independent movements: the colored disk rotating at *rps revolutions per second* and the shutter line sweeping one frame at *fps frames per second*. The ratio rps/fps is the driver of the rolling shutter effect (or the disk rps alone if we normalize the shutter fps to 1 frame per second).  In order to best demonstrate this effect, ratios of rps/fps are taken to be in the range 1.5-2.5&#xD;
&#xD;
This is a colored disk of m pixels wide, rotated over an angle theta.&#xD;
&#xD;
    colors = {RGBColor[1, 0, 1], RGBColor[0.988, 0.73, 0.0195], RGBColor[&#xD;
       0.266, 0.516, 0.9576], RGBColor[0.207, 0.652, 0.324], RGBColor[&#xD;
       0, 0, 1], RGBColor[1, 0, 0]};&#xD;
    colorDisk[theta_, m_, cols_] := &#xD;
     ImageResize[&#xD;
      Image[Graphics[&#xD;
        MapThread[{#3, &#xD;
           Disk[{0, 0}, 1, {#1, #2} + theta]} &amp;amp;, {Pi Range[0, 5, 1]/3, &#xD;
          Pi Range[1, 6]/3, colors}]]], m]&#xD;
&#xD;
A video of the rotating disk consists of a series of frames. Each frame is captured during one passage of the shutter line. The function *angularPosition* links the angular progress of the disk to the frame number (frm) and the row number at the position of the shutter line:&#xD;
&#xD;
    angularPosition[frm_, row_, rps_, &#xD;
      m_] := -2 Pi (-1 + (-1 + frm) m + row) rps/m&#xD;
&#xD;
Th function *diskFrameImage* computes the result of the shutter line swiping a colored disk (of size m, rotating at rps revolutions per second) at frame number frm and up to row number toRow:&#xD;
&#xD;
    diskFrameImage[frm_, toRow_, rps_, m_, cols_] := &#xD;
     ImageAssemble[&#xD;
      Transpose@{ParallelTable[&#xD;
         ImageTake[&#xD;
          colorDisk[angularPosition[frm, r, rps, m], m, colors], {r}], {r,&#xD;
           toRow}]}]&#xD;
&#xD;
This is the first frame of a video of a disk rotating at a speed ratio rps/fps of 1 : &#xD;
&#xD;
    With[{m = 200, frm = 1, rps = 1}, &#xD;
     diskFrameImage[frm, m, rps, m, colors]]&#xD;
&#xD;
![enter image description here][4]&#xD;
&#xD;
This shows the influence of the disk rps/fps ratio on the appearance of the first frame  captured: &#xD;
&#xD;
    With[{m = 200, frm = 1}, &#xD;
     Grid[{{&amp;#034;rps=0.512&amp;#034;, &amp;#034;rps=1.512&amp;#034;, &amp;#034;rps=2.512&amp;#034;}, &#xD;
       diskFrameImage[frm, m, #, m, colors] &amp;amp; /@ {.512, 1.512, 2.512}}]]&#xD;
&#xD;
![enter image description here][5]&#xD;
&#xD;
Below is a GIF showing the capture of the first frame of a disk rotating at rps/fps 1. The code is used to generate all of the following GIFs.&#xD;
&#xD;
    With[{m = 200, frm = 1, rps = 1.},&#xD;
     Animate[&#xD;
      Grid[{{&#xD;
         ImageCompose[&#xD;
          colorDisk[angularPosition[frm, row, rps, m], m, colors], &#xD;
          Graphics[Line[{{-m, 0}, {m, 0}}]], Scaled[{.5, (m - row)/m}]],&#xD;
         ImageCompose[diskFrameImage[frm, row, rps, m, colors], &#xD;
          Graphics[Line[{{-m, 0}, {m, 0}}]], Scaled[{.5, .01}]]}}, &#xD;
       Alignment -&amp;gt; Top], {row, 1, m}]]&#xD;
&#xD;
![enter image description here][6]&#xD;
&#xD;
Below are 4 examples showing the capture of the first frame of a video of a rotating disk with a roller shutter at 1fs. The disk rotates at 0.5 rps (top left), 1.0 rps (top right), 1.5 rps (bottom left) and 2.0 rps (bottom right). As the disk rotates faster relative to the shutter, the captured image becomes more complex.&#xD;
&#xD;
![enter image description here][7]&#xD;
&#xD;
![enter image description here][8]&#xD;
&#xD;
The subsequent frames are captured the same way. Below are the first 5 frames of a video of a disk rotating at 1.5123 rps:&#xD;
&#xD;
![enter image description here][9]&#xD;
&#xD;
There ought to be a lot more images that result from the transformation of a rotation into a capture with a rolling shutter. I hope this contribution can inspire more community members.&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=combirotodisk15and2.gif&amp;amp;userId=20103&#xD;
  [2]: https://community.wolfram.com/groups/-/m/t/2489445&#xD;
  [3]: https://upload.wikimedia.org/wikipedia/commons/1/15/Rolling_shutter_effect_animation.gif&#xD;
  [4]: https://community.wolfram.com//c/portal/getImageAttachment?filename=8345locusfulldiskrps1.png&amp;amp;userId=68637&#xD;
  [5]: https://community.wolfram.com//c/portal/getImageAttachment?filename=9528colordiskrpscompare.png&amp;amp;userId=68637&#xD;
  [6]: https://community.wolfram.com//c/portal/getImageAttachment?filename=newrotodiskfrm1rps05small.gif&amp;amp;userId=68637&#xD;
  [7]: https://community.wolfram.com//c/portal/getImageAttachment?filename=combirotodisk05and10.gif&amp;amp;userId=68637&#xD;
  [8]: https://community.wolfram.com//c/portal/getImageAttachment?filename=combirotodisk15and2.gif&amp;amp;userId=68637&#xD;
  [9]: https://community.wolfram.com//c/portal/getImageAttachment?filename=allframesvideofinal.gif&amp;amp;userId=68637&#xD;
&#xD;
 [at0]: https://community.wolfram.com/web/ghurst</description>
    <dc:creator>Erik Mahieu</dc:creator>
    <dc:date>2022-06-02T12:22:57Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/3067969">
    <title>None of the countries bordering Poland before 1990 exist today: the fall of the Berlin Wall and USSR</title>
    <link>https://community.wolfram.com/groups/-/m/t/3067969</link>
    <description>![enter image description here][1]&#xD;
&#xD;
&amp;amp;[Wolfram Notebook][2]&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=_2_ezgif.com-optimizecopy.gif&amp;amp;userId=11733&#xD;
  [2]: https://www.wolframcloud.com/obj/34c7205a-40cd-4587-b6a1-f1fadc1ed8ce</description>
    <dc:creator>Vitaliy Kaurov</dc:creator>
    <dc:date>2023-11-21T01:14:10Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/2763509">
    <title>Optimize search for rational numbers on unit circle?</title>
    <link>https://community.wolfram.com/groups/-/m/t/2763509</link>
    <description>*Crossposted: https://mathematica.stackexchange.com/q/278250/13 *&#xD;
&#xD;
![enter image description here][1]&#xD;
&#xD;
&#xD;
&amp;amp;[Wolfram Notebook][2]&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=RealRational_560.jpg&amp;amp;userId=11733&#xD;
  [2]: https://www.wolframcloud.com/obj/4dd2dfe1-b258-4a55-a8c4-39f6b4f0cfe9</description>
    <dc:creator>Vitaliy Kaurov</dc:creator>
    <dc:date>2023-01-06T18:30:28Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/3022104">
    <title>Can Wolfram&amp;#039;s new compiler technology speed up this AABB tree code?</title>
    <link>https://community.wolfram.com/groups/-/m/t/3022104</link>
    <description>An axes aligned bounding box (AABB) tree, a type of [bounding volume hierarchy](https://en.wikipedia.org/wiki/Bounding_volume_hierarchy), is a spatial data structure designed to efficiently find overlapping bounding boxes. It is often used to find broad-level collisions in applications such as collision detection and ray tracing.&#xD;
&#xD;
## Question&#xD;
&#xD;
I have an implementation in WL that uses some [`Compile`](https://reference.wolfram.com/language/ref/Compile) and [`DataStructure`](https://reference.wolfram.com/language/ref/DataStructure), but is mostly top-level WL code. I&amp;#039;m looking to increase performance, while staying in the WL ecosystem.&#xD;
&#xD;
Are there any tips to speed up my code? In particular any tips to port this over to compiled code using [`FunctionCompile`](https://reference.wolfram.com/language/ref/FunctionCompile.html) &amp;amp; friends? Side note, would be nice if this was a builtin `DataStructure` :)&#xD;
&#xD;
I&amp;#039;ve posted the code below. Feel free to ask any questions about how it works, etc.&#xD;
&#xD;
## Examples&#xD;
&#xD;
### Basic example&#xD;
&#xD;
Bounding boxes are of the form $\{\{x_{min}, x_{max}\}, \{y_{min}, y_{max}\}, \{z_{min}, z_{max}\}\}$.&#xD;
&#xD;
Let&amp;#039;s create the AABB tree over 3 bounding boxes and make 1 query bounding box:&#xD;
&#xD;
    bboxes = {&#xD;
      {{0, 1}, {0, 1}, {0, 1}},&#xD;
      {{0.5, 1.5}, {0.25, 1.5}, {0.3, 0.7}}, &#xD;
      {{0.7, 0.8}, {0.8, 2}, {0.2, 0.8}}&#xD;
    };&#xD;
    testbbox = {{0.6, 0.9}, {1.1, 1.4}, {0.6, 0.9}};&#xD;
Create the data structure:&#xD;
&#xD;
    aabbtree = AABBTree[bboxes];&#xD;
&#xD;
Find the indices of the bounding boxes that overlap `testbbox`:&#xD;
&#xD;
    overlaps = OverlappingBBoxes[aabbtree, testbbox]&#xD;
    (* {2, 3} *)&#xD;
Visualize (query box in blue, overlapping in red, disjoint in green):&#xD;
&#xD;
    Graphics3D[{&#xD;
      {FaceForm[Green], Cuboid @@@ Transpose[Delete[bboxes, Partition[overlaps, 1]], {1, 3, 2}]},&#xD;
      {FaceForm[Red], Cuboid @@@ Transpose[bboxes[[overlaps]], {1, 3, 2}]},&#xD;
      {Blue, Cuboid @@ Transpose[testbbox]}&#xD;
     }]&#xD;
&amp;lt;img src=&amp;#034;https://community.wolfram.com//c/portal/getImageAttachment?filename=Screenshot2023-09-26at10.48.42AM.png&amp;amp;userId=46025&amp;#034; width=&amp;#034;360&amp;#034;&amp;gt;&#xD;
&#xD;
### 4000 bounding boxes, 1 query&#xD;
&#xD;
    randomBBox[n_] :=&#xD;
      With[{llcorners = RandomReal[{-10, 10}, {n, 3}]},&#xD;
        Transpose[{llcorners, llcorners + RandomReal[{1, 1}, {n, 3}]}, {3, 1, 2}]&#xD;
      ]&#xD;
    &#xD;
    SeedRandom[1];&#xD;
    bboxes = randomBBox[4000];&#xD;
    testbbox = randomBBox[1][[1]];&#xD;
    &#xD;
    aabbtree = AABBTree[bboxes]; // AbsoluteTiming&#xD;
    (* {0.018875, Null} *)&#xD;
    &#xD;
    (overlaps = OverlappingBBoxes[aabbtree, testbbox]) // AbsoluteTiming&#xD;
    (* {0.000692, {1817, 3935, 878, 87}} *)&#xD;
    &#xD;
    Graphics3D[Cuboid @@@ Transpose[bboxes, {1, 3, 2}]]&#xD;
&amp;lt;img src=&amp;#034;https://community.wolfram.com//c/portal/getImageAttachment?filename=Screenshot2023-09-26at10.52.43AM.png&amp;amp;userId=46025&amp;#034; width=&amp;#034;360&amp;#034;&amp;gt;&#xD;
&#xD;
    Graphics3D[{&#xD;
      {FaceForm[Green], Cuboid @@@ Transpose[Delete[bboxes, Partition[overlaps, 1]], {1, 3, 2}]},&#xD;
      {FaceForm[Red], Cuboid @@@ Transpose[bboxes[[overlaps]], {1, 3, 2}]},&#xD;
      {Blue, Cuboid @@ Transpose[testbbox]}},&#xD;
     PlotRange -&amp;gt; testbbox,&#xD;
     PlotRangePadding -&amp;gt; Scaled[0.25]&#xD;
    ]&#xD;
&amp;lt;img src=&amp;#034;https://community.wolfram.com//c/portal/getImageAttachment?filename=Screenshot2023-09-26at10.52.58AM.png&amp;amp;userId=46025&amp;#034; width=&amp;#034;360&amp;#034;&amp;gt;&#xD;
&#xD;
### 100000 bounding boxes, 100000 queries&#xD;
&#xD;
    SeedRandom[1];&#xD;
    bboxes = randomBBox[100000];&#xD;
    testbboxes = randomBBox[100000];&#xD;
    &#xD;
    aabbtree = AABBTree[bboxes]; // AbsoluteTiming&#xD;
    (* {0.235465, Null} *)&#xD;
    &#xD;
    OverlappingBBoxes[aabbtree, testbboxes[[1]]]; // AbsoluteTiming&#xD;
    (* {0.001988, Null} *)&#xD;
&#xD;
I suspect this can be sped up substantially:&#xD;
&#xD;
    Scan[OverlappingBBoxes[aabbtree, #]&amp;amp;, testbboxes]; // AbsoluteTiming&#xD;
    (* {44.8445, Null} *)&#xD;
&#xD;
## Code&#xD;
&#xD;
    AABBTree[bboxes_] :=&#xD;
    	Block[{$RecursionLimit = ∞},&#xD;
    		iAABBTree[1, MapIndexed[Join, Flatten /@ bboxes][[Ordering[bboxes[[All, 1, 1]]]]]]&#xD;
    	]&#xD;
    &#xD;
    iAABBTree[d_, bboxestagged_] :=&#xD;
    	Block[{len, n, x, Sleft, Scent, Sright, node},&#xD;
    		len = Length[bboxestagged];&#xD;
    		If[len &amp;lt;= 16, Return[centerNode3D[d, Null, bboxestagged]]];&#xD;
    		&#xD;
    		n = Ordering[bboxestagged[[All, 2d-1]], {Quotient[len+1, 2]}][[1]];&#xD;
    		x = Mean[bboxestagged[[n, 2d-1 ;; 2d]]];&#xD;
    		&#xD;
    		{Sleft, Scent, Sright} = partitionIntervals3D[d, bboxestagged, x];&#xD;
    		&#xD;
    		node = centerNode3D[d, x, Scent];&#xD;
    		If[Length[Sleft] &amp;gt; 0, node[&amp;#034;SetLeft&amp;#034;, iAABBTree[Mod[d+1, 3, 1], Sleft]];];&#xD;
    		If[Length[Sright] &amp;gt; 0, node[&amp;#034;SetRight&amp;#034;, iAABBTree[Mod[d+1, 3, 1], Sright]];];&#xD;
    		&#xD;
    		node&#xD;
    	]&#xD;
    &#xD;
    centerNode3D[d_, x_, {}] := CreateDataStructure[&amp;#034;BinaryTree&amp;#034;, {x, {}, {}, {}, {}, {}, {}, {}, -$MaxMachineNumber, $MaxMachineNumber, d}]&#xD;
    &#xD;
    (* {center ordinate, xmins, ymins, zmins, xmaxs, ymaxs, zmaxs, inds, dmin, dmax, d} *)&#xD;
    (* xmins are the xmin values of all bboxes in this node, ymins, etc follow suit *)&#xD;
    (* inds are the respective indices of the bboxes in this node *)&#xD;
    (* dmin &amp;amp; dmax are the bounds of all bounding boxes in dimension d (the splitting dimension) *)&#xD;
    centerNode3D[d_, x_, intstagged_] := &#xD;
    	CreateDataStructure[&amp;#034;BinaryTree&amp;#034;, &#xD;
    		{&#xD;
    			x, &#xD;
    			#1, #2, &#xD;
    			#3, #4, &#xD;
    			#5, #6, &#xD;
    			Developer`ToPackedArray[#7, Integer], &#xD;
    			Switch[d, 1, #1[[1]], 2, Min[#3], 3, Min[#5]], Max[Switch[d, 1, #2, 2, #4, 3, #6]], &#xD;
    			d&#xD;
    		}&amp;amp; @@ Transpose[intstagged]&#xD;
    	]&#xD;
    &#xD;
    partitionIntervals3D[d_, intstagged_, x_] :=&#xD;
    	Block[{data, spec},&#xD;
    		data = Partition[partitionIntervals3DC[d, intstagged, x], 7];&#xD;
    		spec = Round[data[[-1]]];&#xD;
    		&#xD;
    		{data[[1 ;; spec[[1]]]], data[[spec[[1]]+1 ;; spec[[2]]]], data[[spec[[2]]+1 ;; -2]]}&#xD;
    	]&#xD;
    &#xD;
    partitionIntervals3DC = Compile[{{d, _Integer}, {intstagged, _Real, 2}, {x, _Real}},&#xD;
    	Block[{mnp, mxp, cright = 0., ccenter = 0., bagright = Internal`Bag[Most[{0.}]], bagcenter = Internal`Bag[Most[{0.}]], bagleft = Internal`Bag[Most[{0.}]]},&#xD;
    		mnp = 2d-1;&#xD;
    		mxp = mnp+1;&#xD;
    		Do[&#xD;
    			If[Compile`GetElement[i, mxp] &amp;lt; x,&#xD;
    				Internal`StuffBag[bagright, i, 1];&#xD;
    				cright++,&#xD;
    				If[Compile`GetElement[i, mnp] &amp;gt; x,&#xD;
    					Internal`StuffBag[bagleft, i, 1],&#xD;
    					Internal`StuffBag[bagcenter, i, 1];&#xD;
    					ccenter++&#xD;
    				]&#xD;
    			],&#xD;
    			{i, intstagged}&#xD;
    		];&#xD;
    		&#xD;
    		Join[Internal`BagPart[bagright, All], Internal`BagPart[bagcenter, All], Internal`BagPart[bagleft, All], {cright, cright + ccenter, 0., 0., 0., 0., 0.}]&#xD;
    	],&#xD;
    	CompilationTarget -&amp;gt; &amp;#034;C&amp;#034;,&#xD;
    	RuntimeOptions -&amp;gt; &amp;#034;Speed&amp;#034;&#xD;
    ];&#xD;
    &#xD;
    OverlappingBBoxes[tree_?DataStructureQ, bbox:{{x1_, x2_}, {y1_, y2_}, {z1_, z2_}}] :=&#xD;
    	Block[{bag, stack, node, a, b, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11},&#xD;
    		bag = Internal`Bag[];&#xD;
    		stack = CreateDataStructure[&amp;#034;Stack&amp;#034;];&#xD;
    		stack[&amp;#034;Push&amp;#034;, tree];&#xD;
    		&#xD;
    		While[!stack[&amp;#034;EmptyQ&amp;#034;],&#xD;
    			node = stack[&amp;#034;Pop&amp;#034;];&#xD;
    			{d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11} = node[&amp;#034;Data&amp;#034;];&#xD;
    			{a, b} = bbox[[d11]];&#xD;
    			If[Length[d2] &amp;gt; 0 &amp;amp;&amp;amp; (d9 &amp;lt;= a &amp;lt;= d10 || d9 &amp;lt;= b &amp;lt;= d10 || a &amp;lt;= d9 &amp;lt;= d10 &amp;lt;= b),&#xD;
    				Internal`StuffBag[bag, Pick[d8, bboxOverlaps[d2, d3, d4, d5, d6, d7, x1, x2, y1, y2, z1, z2], 1], 1];&#xD;
    			];&#xD;
    			&#xD;
    			If[d1 =!= Null, &#xD;
    				If[a &amp;lt; d1 &amp;amp;&amp;amp; !node[&amp;#034;LeftNullQ&amp;#034;], stack[&amp;#034;Push&amp;#034;, node[&amp;#034;Left&amp;#034;]]];&#xD;
    				If[d1 &amp;lt; b &amp;amp;&amp;amp; !node[&amp;#034;RightNullQ&amp;#034;], stack[&amp;#034;Push&amp;#034;, node[&amp;#034;Right&amp;#034;]]];&#xD;
    			];&#xD;
    		];&#xD;
    		&#xD;
    		Internal`BagPart[bag, All]&#xD;
    	]&#xD;
    &#xD;
    bboxOverlaps = Compile[{{epx1, _Real}, {epx2, _Real}, {epy1, _Real}, {epy2, _Real}, {epz1, _Real}, {epz2, _Real}, {x1, _Real}, {x2, _Real}, {y1, _Real}, {y2, _Real}, {z1, _Real}, {z2, _Real}}, &#xD;
    	Boole @ And[&#xD;
    		epx1 &amp;lt;= x1 &amp;lt;= epx2 || epx1 &amp;lt;= x2 &amp;lt;= epx2 || (x1 &amp;lt;= epx1 &amp;lt;= epx2 &amp;lt;= x2),&#xD;
    		epy1 &amp;lt;= y1 &amp;lt;= epy2 || epy1 &amp;lt;= y2 &amp;lt;= epy2 || (y1 &amp;lt;= epy1 &amp;lt;= epy2 &amp;lt;= y2),&#xD;
    		epz1 &amp;lt;= z1 &amp;lt;= epz2 || epz1 &amp;lt;= z2 &amp;lt;= epz2 || (z1 &amp;lt;= epz1 &amp;lt;= epz2 &amp;lt;= z2)&#xD;
    	],&#xD;
    	CompilationTarget -&amp;gt; &amp;#034;C&amp;#034;,&#xD;
    	Parallelization -&amp;gt; True,&#xD;
    	RuntimeOptions -&amp;gt; &amp;#034;Speed&amp;#034;,&#xD;
    	RuntimeAttributes -&amp;gt; {Listable}&#xD;
    ];</description>
    <dc:creator>Greg Hurst</dc:creator>
    <dc:date>2023-09-26T15:12:15Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/96823">
    <title>Simple, fast compiled peak detection based on moving average</title>
    <link>https://community.wolfram.com/groups/-/m/t/96823</link>
    <description>Recently [b][url=http://community.wolfram.com/groups/-/m/t/91868]Christopher coded a neat wavelet-based method for peak detection[/url][/b]. Peak detection is often needed in various scientific fields: all sorts of spectral analysis, time series and general feature recognition in data come to mind right away.  There are many methods for peak detection. Besides his wavelet-based code Christopher also mentions a built-in MaxDetect function rooted in image processing. [b][url=http://reference.wolfram.com/mathematica/ref/MaxDetect.html]MaxDetect[/url][/b], though, being a rather elaborate tool for multi-dimensional data (2D, 3D images) and with a specific image-processing-minded parameter tuning, was not meant to target time series and other 1D data. This got me thinking.

[b]Can we come up with a minimal compile-able peak detection code that would be accurate, robust and fast in most situations for 1D data?[/b]

I am not an expert in the subject, but intuitively peak detection consists of two stages. 
[list]
[*][b]Finding all maxima[/b]. This can be done via Differences with selection of neighbor difference pairs that change from positive to negative. Such pair would indicate local maximum.
[*][b]Filtering out peaks[/b]. Selecting those maxima that are high splashes of amplitude with respect to its immediate neighborhood. Quoted words are relative and depend on particular data. This is why they are set as tuning parameters in the algorithm.
[/list]To illustrate 2nd point lets take a look at the [b][url=http://www.wolframalpha.com/input/?i=Albert+Einstein+Wikipedia+page+hits+history]Albert Einstein Wikipedia page hits history[/url][/b] below. Obviously a large peak in the past can be lower than current average in case if there is strong trend in the data. This is why we need windowing when looking for peaks, - to compare a peak to its immediate neighborhood. 

[url=http://www.wolframalpha.com/input/?i=Albert+Einstein+Wikipedia+page+hits+history][img=width: 600px; height: 469px;]/c/portal/getImageAttachment?filename=ScreenShot2013-08-14at3.13.07PM.png&amp;amp;userId=11733[/img][/url]

Without further ado here is a function written specifically in terms of functions that can be compiled. For example I do not use MovingAverage, but do trick with Partition instead.[mcode]PeakDetect = Compile[{{data, _Real, 1}, {width, _Integer}, {cut, _Real}}, (Table[0, {width}]~Join~
      Map[UnitStep[# - cut] &amp;amp;, data[[1 + width ;; -1 - width]] - Map[Mean, Partition[data, 1 + 2 width, 1]]]~Join~
      Table[0, {width}]) ({0}~Join~ Map[Piecewise[{{1, Sign[#] == {1, -1}}, {0, Sign[#] != {1, -1}}}] &amp;amp;, 
       Partition[Differences[data], 2, 1]]~Join~{0}), CompilationTarget -&amp;gt; &amp;#034;C&amp;#034;];[/mcode]The legend for the function arguments is the following:[list]
[*]data  1D numerical list of data
[*]width  half-width of the moving average window not including central point
[*]cut  threshold at which to cut off the peak in natural units of data amplitudes 
[/list]Now lets see some usage cases. Lets import the same Albert Einstein data as a proof of concept. [mcode]raw = WolframAlpha[ &amp;#034;albert einstein&amp;#034;, {{&amp;#034;PopularityPod:WikipediaStatsData&amp;#034;, 1}, &amp;#034;TimeSeriesData&amp;#034;}];
data = raw[[All, 2]][[All, 1]];[/mcode]We use total window width of 5 points here and cut off peak at a standard deviation of the whole data. The peak labeled May 2008 is nicely picked up even though it is comparable then current average. This peak is most probably due to publication on May 13, 2008 of [b][url=http://www.amazon.com/Einstein-Life-Universe-Walter-Isaacson/dp/0743264746]one of the most famous books about Einstein[/url][/b] marked as New York Times bestseller that also got award Quill Award. Of course you can play with controls to pick or drop peaks. On the top plot one sees data, moving average, and bands formed by moving average displaced up and down by fraction of standard deviation. Any maximum above the top band becomes a peak.

[url=http://www.amazon.com/Einstein-Life-Universe-Walter-Isaacson/dp/0743264746][img=width: 800px; height: 382px;]/c/portal/getImageAttachment?filename=9672ScreenShot2013-08-14at3.47.18PM.png&amp;amp;userId=11733[/img][/url]

The code for the app is at the very end. Lets try a different data set  recent sun spot activity. [mcode]raw = WolframAlpha[&amp;#034;sun spot&amp;#034;, {{&amp;#034;SunspotsPartialTimeSeries:SpaceWeatherData&amp;#034;, 1}, &amp;#034;TimeSeriesData&amp;#034;}];
data = raw[[All, 2]];[/mcode]We right away found on May 2013 mark - a [b][url=http://en.wikipedia.org/wiki/Solar_cycle_24#May_2013]most powerful recent event described in Wikipedia page here[/url][/b]. Please let me know if you have suggestions how to speed this up or improve it generally. I would be very curious to know your opinion and critique. 

[color=#ff0000][i]The .GIF below is large - wait till it is loaded.[/i][/color]

[img=width: 800px; height: 380px;]/c/portal/getImageAttachment?filename=sunspot.gif&amp;amp;userId=11733[/img]

The following reference could be useful:[list]
[*][b][url=http://www.tcs-trddc.com/trddc_website/pdf/SRL/Palshikar_SAPDTS_2009.pdf]Simple Algorithms for Peak Detection in Time-Series[/url][/b]
[*][b][url=http://www.mdpi.com/1999-4893/5/4/588]An Efficient Algorithm for Automatic Peak Detection in Noisy Periodic and Quasi-Periodic Signals[/url][/b]
[/list]The code for the interactive app:[mcode]Manipulate[
 tt = {#, 
     Rotate[DateString[#, {&amp;#034;MonthNameShort&amp;#034;, &amp;#034; &amp;#034;, &amp;#034;Year&amp;#034;}], Pi/2]} &amp;amp; /@
    Pick[raw, PeakDetect[data, wid, thr StandardDeviation[data]], 1][[
    All, 1]];
 
 Column[{
   
   ListLinePlot[{data, 
     ArrayPad[MovingAverage[data, 1 + 2 wid], wid, &amp;#034;Fixed&amp;#034;], 
     ArrayPad[MovingAverage[data, 1 + 2 wid], wid, &amp;#034;Fixed&amp;#034;] + 
      thr StandardDeviation[data], 
     ArrayPad[MovingAverage[data, 1 + 2 wid], wid, &amp;#034;Fixed&amp;#034;] - 
      thr StandardDeviation[data]}, AspectRatio -&amp;gt; 1/6, 
    ImageSize -&amp;gt; 800, Filling -&amp;gt; {2 -&amp;gt; {1}, 3 -&amp;gt; {4}}, 
    FrameTicks -&amp;gt; {None, Automatic}, 
    FillingStyle -&amp;gt; {Directive[Red, Opacity[.7]], 
      Directive[Blue, Opacity[.7]], Directive[Gray, Opacity[.1]]}, 
    PlotStyle -&amp;gt; Opacity[.7], PlotRange -&amp;gt; All, Frame -&amp;gt; True, 
    GridLines -&amp;gt; Automatic, PlotRangePadding -&amp;gt; 0],
   
   Show[
    DateListPlot[raw, Joined -&amp;gt; True, AspectRatio -&amp;gt; 1/6, 
     ImageSize -&amp;gt; 800, Filling -&amp;gt; Bottom, Ticks -&amp;gt; {tt, Automatic}, 
     Frame -&amp;gt; False, Mesh -&amp;gt; All, PlotRange -&amp;gt; All],
    DateListPlot[
     If[# == {}, raw[[1 ;; 2]], #, #] &amp;amp;[
      Pick[raw, PeakDetect[data, wid, thr StandardDeviation[data]], 
       1]], AspectRatio -&amp;gt; 1/6, ImageSize -&amp;gt; 800, 
     PlotStyle -&amp;gt; Directive[Red, PointSize[.007]], PlotRange -&amp;gt; All]
    , PlotRangePadding -&amp;gt; {0, Automatic}]
   
   }],
 Row[{
   Control[{{thr, 1, &amp;#034;threshold&amp;#034;}, 0, 2, Appearance -&amp;gt; &amp;#034;Labeled&amp;#034;}], 
   Spacer[100],
   Control[{{wid, 3, &amp;#034;hal-width&amp;#034;}, 1, 10, 1, Setter}]
   }]
 ][/mcode]
[b]============== UPDATE =================[/b]

Thank you all very much for contributing. I collected everyone&amp;#039;s efforts and Danny&amp;#039;s two functions in a single completely compile-able expression which seems to give shortest time; - but just vaguely faster then Danny&amp;#039;s ingenious maneuver. I very much liked format suggested by Christopher, the one that Michael also kept in his packages. But I wanted to make some benchmarking and thus followed the format returned by the function [b][url=http://reference.wolfram.com/mathematica/ref/MaxDetect.html]MaxDetect[/url][/b] - simply for the sake of speed comparison. This format is just a binary list of the length of original data with 1s in positions of found peaks. 

Here is the function:[mcode]PeakDetect = 
  Compile[{{data, _Real, 1}, {width, _Integer}, {cut, _Real}}, 
   (Table[0, {width}]~Join~
      UnitStep[
       Take[data, {1 + width, -1 - width}] - 
          (Module[{tot = Total[#1[[1 ;; #2 - 1]]], last = 0.}, 
              Table[tot = tot + #1[[j + #2]] - last; 
               last = #1[[j + 1]];
               tot, {j, 0, Length[#1] - #2}]]/#2) &amp;amp;[data, 1 + 2 width] - cut]
    ~Join~Table[0, {width}]) ({0}~Join~
      Table[If[Sign[{data[[ii + 1]] - data[[ii]], 
           data[[ii + 2]] - data[[ii + 1]]}] == {1, -1}, 1, 0], 
           {ii, 1, Length[data] - 2}]~Join~{0}), CompilationTarget -&amp;gt; &amp;#034;C&amp;#034;];
dat = RandomReal[1, 10^7];

pks = MaxDetect[dat]; // AbsoluteTiming
Total[pks]
(* ======== output ======== 
{62.807928, Null}
3333361
   ======== output ======== *)

pks = PeakDetect[dat, 1, 0]; // AbsoluteTiming
Total[pks]
(* ======== output ======== 
{1.560074, Null}
3333360
   ======== output ======== *)[/mcode]And here are the speed benchmarks on 10 million data points which shows 40 times speed-up:</description>
    <dc:creator>Vitaliy Kaurov</dc:creator>
    <dc:date>2013-08-14T21:21:54Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/3024465">
    <title>Global population distribution: what&amp;#039;s a Valeriepieris circle, and where 99% of us live</title>
    <link>https://community.wolfram.com/groups/-/m/t/3024465</link>
    <description>![enter image description here][1]&#xD;
&#xD;
&amp;amp;[Wolfram Notebook][2]&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=Leadimage2.png&amp;amp;userId=20103&#xD;
  [2]: https://www.wolframcloud.com/obj/1bbdeed3-67fe-4d71-b844-4827250a00a6</description>
    <dc:creator>Jari Kirma</dc:creator>
    <dc:date>2023-09-30T08:43:43Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/2434669">
    <title>Date-related functions: revision and performance comparison</title>
    <link>https://community.wolfram.com/groups/-/m/t/2434669</link>
    <description>&amp;gt; *GitHub repository:* https://github.com/ben-izd/cDateFunctions&#xD;
&#xD;
&#xD;
Recently, I was working on an [infographic](https://mathematica.meta.stackexchange.com/a/2608/77079) which heavily involves working with dates and times. After using `DateObject` and some date-related functions, it surprises me how slow they are (in the context of tens of thousands of samples). So I decided to rewrite the main one (`DateDifference`) in Wolfram language. But after seeing the performance boost gained by rewriting, I decided to write some other functions too.  After a couple of months, I end up rewriting 19 functions in wolfram language and 9 in kernel-level (with Rust), in this post you&amp;#039;ll see the result and interesting points I discovered in this journey.&#xD;
&#xD;
&#xD;
&#xD;
Before we start, remember these notes:&#xD;
&#xD;
- Most of the implementations were done with minimum options, many of them do not support options that their built-in ones support (like `TimeZone`, `TimeSystem`, ...) and functions in the first section written in pure Wolfram language without using `Compile` or related functions&#xD;
&#xD;
- Default calendar is `&amp;#034;Gregorian&amp;#034;`, which doesn&amp;#039;t have year `0` (is also true for `&amp;#034;ArithmeticPersian&amp;#034;` calendar) unless it specified&#xD;
&#xD;
- In the &amp;#039;Possible Issues/Bugs + Suggestions&amp;#039; section order is not important, some of them relate to the design decisions that developers decided (it would be awesome to shed some light on them)&#xD;
&#xD;
- All the implementations have the same name with &amp;#039;c&amp;#039; added to start (`DayName` is `cDayName`, which has nothing to do with `C` language)&#xD;
&#xD;
- Some built-in functions were not `Listable`, which is understandable because of date formats like `DateList`, but some of my implementations are `Listable`&#xD;
&#xD;
- All the functions were tested with a wide range of random dates and numbers - Except some cases which will be discussed. The result of the functions with their built-in ones are equal. If you find any case with a wrong result, please comment it &#xD;
&#xD;
- Platform is Mathematica 13.0.0 for Microsoft Windows 10 20H2 (64-bit) on AMD Ryzen 1700 with 16 GB RAM with time-zone offset: +3.5&#xD;
&#xD;
- You can access the code in [GitHub](https://github.com/ben-izd/cDateFunctions) which also include the `LibraryLink` section (`DLL` files and their source code)&#xD;
&#xD;
&#xD;
# Performance Comparison&#xD;
&#xD;
Here are the result of comparing c* functions with their built-in ones in terms of timing (`RepeatedTiming` were used). Tested on different input formats and the number shown here is the floored average of the result.&#xD;
&#xD;
## LeapYearQ&#xD;
![LeapYearQ Comparison](https://i.imgur.com/aE13iXu.jpg)&#xD;
&#xD;
## DayName&#xD;
![DayName Comparison](https://i.imgur.com/o0zBlBI.jpg)&#xD;
&#xD;
## BusinessDayQ&#xD;
![BusinessDayQ Comparison](https://i.imgur.com/UL6Bu4n.jpg)&#xD;
&#xD;
## DayMatchQ&#xD;
![DayMatchQ Comparison](https://i.imgur.com/a4ttizZ.jpg)&#xD;
&#xD;
## DayRound&#xD;
![DayRound Comparison](https://i.imgur.com/F3pF3Uf.jpg)&#xD;
&#xD;
## DateBounds&#xD;
![DateBounds Comparison](https://i.imgur.com/1jhLjzx.jpg)&#xD;
&#xD;
## DateOverlapQ&#xD;
![DateOverlapQ Comparison](https://i.imgur.com/wgRiX8Q.jpg)&#xD;
&#xD;
## DateWithinQ&#xD;
![DateWithinQ Comparison](https://i.imgur.com/3EXUM7C.jpg)&#xD;
&#xD;
## DayCount&#xD;
![DayCount Comparison](https://i.imgur.com/yxec7yo.jpg)&#xD;
&#xD;
## CurrentDate&#xD;
![CurrentDate Comparison](https://i.imgur.com/Z0bfRwr.jpg)&#xD;
&#xD;
## NextDate&#xD;
![NextDate Comparison](https://i.imgur.com/vzFyzqC.jpg)&#xD;
&#xD;
## PreviousDate&#xD;
![PreviousDate Comparison](https://i.imgur.com/DGgCKhR.jpg)&#xD;
&#xD;
## DateDifference&#xD;
![DateDifference Comparison](https://i.imgur.com/JK3d1vW.jpg)&#xD;
&#xD;
## DayPlus&#xD;
![DayPlus Comparison](https://i.imgur.com/XSN1wMi.jpg)&#xD;
&#xD;
## DatePlus&#xD;
![DayPlus Comparison](https://i.imgur.com/TFL1xIt.jpg)&#xD;
![DayPlus Comparison](https://i.imgur.com/hycM3m8.jpg)&#xD;
&#xD;
## DayRangee&#xD;
![DayRange Comparison](https://i.imgur.com/rxGTFGR.jpg)&#xD;
&#xD;
## DateRange&#xD;
![DateRange Comparison](https://i.imgur.com/XaxUcDs.jpg)&#xD;
&#xD;
&#xD;
# Possible Issues/Bugs + Suggestions&#xD;
During testing and developing the code, I notice some strange/unexpected cases + some ideas which I&amp;#039;ll discuss for each function.&#xD;
&#xD;
## LeapYearQ&#xD;
&#xD;
&#xD;
### 1. `&amp;#034;ArithmeticPersian&amp;#034;` uses `&amp;#034;Gregorian&amp;#034;` formula&#xD;
&#xD;
With  `CalendarType -&amp;gt; &amp;#034;ArithmeticPersian&amp;#034;` input will be converted to `&amp;#034;Gregorian&amp;#034;` calendar and the result will be calculated like `CalendarType -&amp;gt; &amp;#034;Gregorian&amp;#034;` (note that they have different formulas):&#xD;
&#xD;
```&#xD;
LeapYearQ[{1403, 1, 1}, CalendarType -&amp;gt; &amp;#034;ArithmeticPersian&amp;#034;]&#xD;
(* Out: True *)&#xD;
&#xD;
LeapYearQ[{1403, 12, 1}, CalendarType -&amp;gt; &amp;#034;ArithmeticPersian&amp;#034;]&#xD;
(* Out: False *)&#xD;
```&#xD;
The reason for above results is that date `{1403, 1, 1}` in `&amp;#034;ArithmeticPersian&amp;#034;` is `{2024, 3, 20}` in `&amp;#034;Gregorian&amp;#034;` which is a leap year in `&amp;#034;Gregorian&amp;#034;` but `{1403, 12, 1}` fall into `{2025, 2, 19}` which is not a leap year, according to `&amp;#034;Gregorian&amp;#034;` calendar.&#xD;
&#xD;
More comprehensive test:&#xD;
&#xD;
```&#xD;
And @@ (&#xD;
  LeapYearQ[{#}, CalendarType -&amp;gt; &amp;#034;ArithmeticPersian&amp;#034;] ===&#xD;
     LeapYearQ[&#xD;
      CalendarConvert[&#xD;
       DateObject[{#}, CalendarType -&amp;gt; &amp;#034;ArithmeticPersian&amp;#034;], &#xD;
       &amp;#034;Gregorian&amp;#034;], CalendarType -&amp;gt; &amp;#034;Gregorian&amp;#034;] &amp;amp; /@ Range[1, 5000])&#xD;
&#xD;
(* Out: True *)&#xD;
```&#xD;
&#xD;
Note that in `&amp;#034;ArithmeticPersian&amp;#034;` leap year gap (which has different methods to calculate, Mathematica uses 2820 period) is 4 and sometimes 5 years which is different than `&amp;#034;Gregorian&amp;#034;`.&#xD;
&#xD;
## BusinessDayQ&#xD;
&#xD;
### 1. Handling `TimeObject` without raising any message (related to AbsoluteTime-1 problem)&#xD;
&#xD;
When using `TimeObject` in `BusinessDayQ`, it will be converted to a date and return a result! instead of raising an error:&#xD;
&#xD;
```&#xD;
DayName[]&#xD;
(* Out: Thursday *)&#xD;
&#xD;
BusinessDayQ[TimeObject[]]&#xD;
(* Out: True *)&#xD;
```&#xD;
&#xD;
## DayMatchQ&#xD;
&#xD;
### 1. Missing/displace Veterans Day&#xD;
&#xD;
Veterans Day which starts in 1938, on YYYY-11-11 except 1971-1978, which was on Oct 4th Monday [\[Source\]](https://www.timeanddate.com/holidays/us/veterans-day). Considering observed holidays (holiday fall on Saturday/Sunday the day before/after will be observed day), a holiday could be either the specified day or a day before or after.&#xD;
&#xD;
```&#xD;
Select[Range[1938, 2050], Not@Or[DayMatchQ[{#, 11, 10}, &amp;#034;Holiday&amp;#034;],&#xD;
    DayMatchQ[{#, 11, 11}, &amp;#034;Holiday&amp;#034;],&#xD;
    DayMatchQ[{#, 11, 12}, &amp;#034;Holiday&amp;#034;]] &amp;amp;]&#xD;
```&#xD;
&#xD;
Result:&#xD;
&#xD;
```&#xD;
{1939, 1940, 1944, 1950, 1961, 1967, 1972, 1978, 1989, 1995, 2000, 2006, 2017, 2023, 2028, 2034, 2045}&#xD;
```&#xD;
&#xD;
which if you apply `Differences`, we&amp;#039;ll get a pattern:&#xD;
&#xD;
```&#xD;
{1, 4, 6, 11, 6, 5, 6, 11, 6, 5, 6, 11, 6, 5, 6, 11}&#xD;
```&#xD;
&#xD;
Some years are missing the holiday and in the range of 1971-1978 it should not be on YYYY-11-11, but for some years it is.&#xD;
&#xD;
Correct result (use `cDayMatchQ` instead of `DayMatchQ`):&#xD;
&#xD;
```&#xD;
{1971, 1972, 1973, 1974, 1975, 1976, 1977}&#xD;
```&#xD;
&#xD;
Also, it misses some dates in the future [\[Source\]](https://www.timeanddate.com/calendar/?year=2045&amp;amp;country=1):&#xD;
&#xD;
```&#xD;
DayMatchQ[{2045, 11, 10}, &amp;#034;Holiday&amp;#034;]&#xD;
(* Out: False *)&#xD;
&#xD;
(* 1 day before/after also is not a holiday*)&#xD;
DayMatchQ[{2045, 11, 9}, &amp;#034;Holiday&amp;#034;]&#xD;
(* Out: False *)&#xD;
&#xD;
DayMatchQ[{2045, 11, 11}, &amp;#034;Holiday&amp;#034;]&#xD;
(* Out: False *)&#xD;
```&#xD;
&#xD;
### 2. Handling `TimeObject` (related to AbsoluteTime-1 problem)&#xD;
&#xD;
When using `TimeObject` in `DayMatchQ`, it will convert it to a date and return the result ! instead of raising an error:&#xD;
&#xD;
```&#xD;
DayName[]&#xD;
(* Out: Thursday *)&#xD;
&#xD;
DayMatchQ[TimeObject[], Thursday]&#xD;
(* Out: True*)&#xD;
```&#xD;
&#xD;
&#xD;
### 3. Documentation typo&#xD;
&#xD;
Based on [`DayMatchQ`](http://reference.wolfram.com/language/ref/DayMatchQ.html) documentation, default value for `DayMatchQ` is `All` while giving error to a single argument:&#xD;
&#xD;
```&#xD;
DayMatchQ[{2021, 11, 12}]&#xD;
```&#xD;
&#xD;
![Error image](https://i.imgur.com/WCp2Ijm.jpg)&#xD;
&#xD;
&#xD;
## DateWithinQ&#xD;
&#xD;
### 1. Does not support `DateList` format for input:&#xD;
&#xD;
The documentation notes that input should be `DateObject` of any calendar, it&amp;#039;s a good feature to support different calendars but what about `DateList` format? What&amp;#039;s the reason behind it? Is it much different from `DateDifference` which supports this format?&#xD;
&#xD;
```&#xD;
DateWithinQ[{2021}, {2021, 1}]&#xD;
```&#xD;
&#xD;
Also, it should be noted that a *Q function in this example returned an `Unevaluated` expression instead of a Boolean, is this a normal behavior?&#xD;
&#xD;
### 2. Returning `Unevaluated` expression without raising any message:&#xD;
&#xD;
```&#xD;
DateWithinQ[DateObject@{2020, 1, 1, 1, 1, 1}, DateObject@{2020, 1, 1}]&#xD;
```&#xD;
![ERROR IMAGE](https://i.imgur.com/FpfGpFr.jpg)&#xD;
&#xD;
## DayCount&#xD;
&#xD;
### 1. Round results&#xD;
&#xD;
If it&amp;#039;s a day and more than half, it adds one day, otherwise, it doesn&amp;#039;t (opposite of what documentation in `Properties &amp;amp; Relations` says, equal to the length of `DayRange` with some options).&#xD;
&#xD;
```&#xD;
DayCount[{2020, 1, 1}, {2020, 1, 1, 11}, All]&#xD;
(* Out: 0 *)&#xD;
&#xD;
DayCount[{2020, 1, 1}, {2020, 1, 1, 13}, All]&#xD;
(* Out: 1 *)&#xD;
```&#xD;
&#xD;
`cDayCount` returns 0 for both of the above cases.&#xD;
&#xD;
### 2. Wrong result in year 1&#xD;
&#xD;
```&#xD;
DayCount[{1, 12, 23}, {2, 3, 25}, &amp;#034;BeginningOfMonth&amp;#034;]&#xD;
(* Out: 13 *)&#xD;
```&#xD;
&#xD;
## NextDate&#xD;
&#xD;
### 1. Inconsistent behavior&#xD;
&#xD;
When using a granularity with an input that doesn&amp;#039;t have enough precision, on most of the types, the upper-bound will be used as a start date to find the next occurrences but not for weekdays (not exactly the upper-bound is used).&#xD;
&#xD;
```&#xD;
NextDate[{2020, 1}, &amp;#034;Day&amp;#034;]&#xD;
(* Out: DateObject[{2020,2,1}, &amp;#034;Day&amp;#034;, &amp;#034;Gregorian&amp;#034;, 3.5`] *)&#xD;
&#xD;
NextDate[{2020, 1}, Sunday]&#xD;
(* Out: DateObject[{2020,1,5}, &amp;#034;Day&amp;#034;, &amp;#034;Gregorian&amp;#034;, 3.5`] *)&#xD;
```&#xD;
Also, note that calendar type and time-zone offset was added to the output (input argument does not have those).&#xD;
&#xD;
&#xD;
### 2. Handling `TimeObject`&#xD;
&#xD;
`NextDate` support `TimeObject`. It can even give us the next `Day` of a `TimeObject`:&#xD;
&#xD;
```&#xD;
First@TimeObject[]&#xD;
(* Out: {15, 38, 31.} *)&#xD;
&#xD;
First@NextDate[TimeObject[], &amp;#034;Hour&amp;#034;]&#xD;
(* Out: {2021, 11, 14, 16} *)&#xD;
&#xD;
First@NextDate[TimeObject[], &amp;#034;Day&amp;#034;]&#xD;
(* Out: {2021, 11, 15} *)&#xD;
```&#xD;
&#xD;
`cNextDate` result:&#xD;
&#xD;
```&#xD;
{16}&#xD;
```&#xD;
&#xD;
### 3. Wrong result in year 1 or -1&#xD;
&#xD;
```&#xD;
DateList@NextDate[{1, 12, 1}, &amp;#034;BeginningOfMonth&amp;#034;]&#xD;
(* Out: {1, 2, 1, 0, 0, 0.} *)&#xD;
&#xD;
DateList@NextDate[{-1, 12, 1, 0, 0, 0}, &amp;#034;Quarter&amp;#034;]&#xD;
(* Out: {-1, 1, 1, 0, 0, 0.} *)&#xD;
```&#xD;
&#xD;
Correct result (`cNextDate`):&#xD;
&#xD;
```&#xD;
{2, 1, 1, 0, 0, 0.}&#xD;
&#xD;
{1, 1, 1, 0, 0, 0.}&#xD;
```&#xD;
&#xD;
### 4. Inconsistent keyword in documentation&#xD;
&#xD;
[`NextDate`](http://reference.wolfram.com/language/ref/NextDate.html) documentation uses `&amp;#034;MonthFirstDay&amp;#034;` and `&amp;#034;MonthLastDay&amp;#034;` instead of `&amp;#034;BeginningOfMonth&amp;#034;` and `&amp;#034;EndOfMonth&amp;#034;`.&#xD;
&#xD;
## DateDifference&#xD;
&#xD;
### 1. Type &amp;#034;quarter&amp;#034;/&amp;#034;Year&amp;#034; includes year 0&#xD;
&#xD;
As noted in the beginning, the `&amp;#034;Gregorian&amp;#034;` calendar in Mathematica doesn&amp;#039;t have year 0 but in these cases it does!&#xD;
&#xD;
```&#xD;
DateDifference[{-1, 9, 1}, {1, 9, 1}, &amp;#034;Quarter&amp;#034;]&#xD;
&#xD;
(* Out: Quantity[9.96739, &amp;#034;QuarterYears&amp;#034;] *)&#xD;
```&#xD;
&#xD;
Correct Result (using `cDateDifference`):&#xD;
&#xD;
```&#xD;
Quantity[4., &amp;#034;QuarterYears&amp;#034;]&#xD;
```&#xD;
&#xD;
How many quarters do you see in this picture?&#xD;
&#xD;
![ERROR IMAGE](https://i.imgur.com/eUXzNry.jpg)&#xD;
&#xD;
Another example:&#xD;
&#xD;
```&#xD;
DateDifference[{-1, 10, 1, 0, 0, 0}, {1, 1, 1, 0, 0, 0}, &amp;#034;Year&amp;#034;]&#xD;
&#xD;
(* Out: Quantity[1.74795, &amp;#034;Years&amp;#034;] *)&#xD;
```&#xD;
&#xD;
### 2. Slightly different result&#xD;
&#xD;
```&#xD;
DateDifference[{2020, 3, 5, 15}, {2020, 7, 15, 5}, &amp;#034;Week&amp;#034;]&#xD;
DateDifference[AbsoluteTime@{2020, 3, 5, 15}, AbsoluteTime@{2020, 7, 15, 5}, &amp;#034;Week&amp;#034;]&#xD;
```&#xD;
&#xD;
Result (see the last digits):&#xD;
&#xD;
```&#xD;
Quantity[18.797619047619047, &amp;#034;Weeks&amp;#034;]&#xD;
Quantity[18.797619047619044, &amp;#034;Weeks&amp;#034;]&#xD;
```&#xD;
&#xD;
`cDateDifference` returns the first result.&#xD;
The real decimal can be calculated manually, which is `67/84` or:&#xD;
&#xD;
```&#xD;
0.7976190476190476&#xD;
```&#xD;
&#xD;
### 3. Raise error for multiple units including `Decade` /`Century` / `Millennium`&#xD;
&#xD;
```&#xD;
DateDifference[{2020, 1, 5}, {2120, 1, 4}, &amp;#034;Decade&amp;#034;]&#xD;
DateDifference[{2020, 1, 5}, {2120, 1, 4}, {&amp;#034;Decade&amp;#034;, &amp;#034;Year&amp;#034;}]&#xD;
cDateDifference[{2020, 1, 5}, {2120, 1, 4}, {&amp;#034;Decade&amp;#034;, &amp;#034;Year&amp;#034;}]&#xD;
```&#xD;
![ERROR IMAGE](https://i.imgur.com/6dINWVa.jpg)&#xD;
&#xD;
## DayPlus&#xD;
&#xD;
### 1. Does not support `Week`&#xD;
&#xD;
It supports `&amp;#034;BeginningOfMonth&amp;#034;` and `&amp;#034;EndOfMonth&amp;#034;` but not `&amp;#034;Week&amp;#034;`:&#xD;
&#xD;
```&#xD;
DayPlus[{2020, 1, 1}, 1, &amp;#034;Week&amp;#034;]&#xD;
```&#xD;
&#xD;
![ERROR IMAGE](https://i.imgur.com/YLkmzPd.jpg)&#xD;
&#xD;
Possible with `cDayPlus`:&#xD;
&#xD;
```&#xD;
{2020, 1, 8}&#xD;
```&#xD;
&#xD;
## DatePlus&#xD;
&#xD;
### 1. Different results with Quantity and List&#xD;
&#xD;
```&#xD;
DatePlus[{2020, 1, 1}, {1, &amp;#034;Quarter&amp;#034;}]&#xD;
(* Out: {2020, 4, 1} *)&#xD;
&#xD;
DatePlus[{2020, 1, 1}, Quantity[1, &amp;#034;QuarterYears&amp;#034;]]&#xD;
(* Out: {2020, 4, 1, 12} *)&#xD;
```&#xD;
&#xD;
### 2. Odd Behavior with year 1&#xD;
&#xD;
```&#xD;
DatePlus[{1, 8, 15}, {3, &amp;#034;EndOfMonth&amp;#034;}]&#xD;
(* Out: {1, 3, 31} *)&#xD;
```&#xD;
&#xD;
Correct result (with `cDatePlus`):&#xD;
&#xD;
```&#xD;
{1, 10, 31}&#xD;
```&#xD;
&#xD;
Another example:&#xD;
&#xD;
```&#xD;
DatePlus[{1, 10, 5}, {2, &amp;#034;BeginningOfMonth&amp;#034;}]&#xD;
(* Out: {1, 3, 1} *)&#xD;
```&#xD;
&#xD;
Correct result:&#xD;
&#xD;
```&#xD;
{1, 12, 1}&#xD;
```&#xD;
&#xD;
### 3. Strange result with an empty list&#xD;
&#xD;
When we use an empty list (`{}`) as offset, it uses the first argument as day offset from now:&#xD;
&#xD;
```&#xD;
First@DatePlus[0, {}]&#xD;
(* Out: {2021, 11, 13, 15, 7, 0.} *)&#xD;
&#xD;
First@DatePlus[1, {}]&#xD;
(* Out: {2021, 11, 14, 15, 7, 0.} *)&#xD;
&#xD;
DatePlus[0, {1, &amp;#034;Day&amp;#034;}]&#xD;
(* Out: 86400 *)&#xD;
```&#xD;
&#xD;
## DayRange&#xD;
&#xD;
### 1. Odd behavior with year 1 or -1&#xD;
&#xD;
It starts from `1-1-31`, just to avoid clutter, you&amp;#039;ll see the length:&#xD;
&#xD;
```&#xD;
Length@DayRange[{1, 7, 9}, {2, 2, 15}, &amp;#034;EndOfMonth&amp;#034;]&#xD;
(* Out: 13 *)&#xD;
&#xD;
Length@DayRange[{-1, 7, 9}, {1, 2, 15}, &amp;#034;EndOfMonth&amp;#034;]&#xD;
(* Out: 12 *)&#xD;
```&#xD;
&#xD;
Proper result (with `cDayRange`):&#xD;
&#xD;
```&#xD;
7&#xD;
&#xD;
7&#xD;
```&#xD;
&#xD;
## DateRange&#xD;
&#xD;
### 1. The backward calculation is done using the forward formula&#xD;
&#xD;
When the end date is larger than the start date, we add the granularity (should be positive) to the start until we reach the end, but if the start is bigger than the end and granularity is negative, we should subtract it from the start until we reach the end. It&amp;#039;s true for all the types except `&amp;#034;BeginningOfMonth&amp;#034;` and `&amp;#034;EndOfMonth&amp;#034;`.&#xD;
&#xD;
```&#xD;
DateRange[{2019, 12, 5}, {2019, 7, 1}, {-3, &amp;#034;BeginningOfMonth&amp;#034;}]&#xD;
(* Out: {{2019, 10, 1, 0, 0, 0.}, {2019, 7, 1, 0, 0, 0.}} *)&#xD;
```&#xD;
&#xD;
Which should be (using `cDateRange`):&#xD;
&#xD;
```&#xD;
{{2019, 12, 1, 0, 0, 0.}, {2019, 9, 1, 0, 0, 0.}}&#xD;
```&#xD;
&#xD;
Pay attention to hour element:&#xD;
&#xD;
```&#xD;
(* Normal *)&#xD;
DateRange[{2019, 12, 5, 12}, {2019, 7, 1}, {-3, &amp;#034;Month&amp;#034;}]&#xD;
(* Out: {{2019, 12, 5, 12, 0, 0.}, {2019, 9, 5, 12, 0, 0.}} *)&#xD;
&#xD;
(* Odd *)&#xD;
DateRange[{2019, 12, 5, 12}, {2019, 7, 1}, {-3, &amp;#034;EndOfMonth&amp;#034;}]&#xD;
(* Out: {{2019, 10, 31, 0, 0, 0.}, {2019, 7, 31, 0, 0, 0.}} *)&#xD;
&#xD;
(* Odd *)&#xD;
DateRange[{2019, 12, 5, 12}, {2019, 7, 1}, {-3, &amp;#034;BeginningOfMonth&amp;#034;}]&#xD;
(* Out: {{2019, 10, 1, 0, 0, 0.}, {2019, 7, 1, 0, 0, 0.}} *)&#xD;
```&#xD;
&#xD;
In other terms, the result of the examples below are equal except in different ordering:&#xD;
&#xD;
```&#xD;
DateRange[{2019, 12, 5}, {2019, 7, 1}, {-3, &amp;#034;BeginningOfMonth&amp;#034;}]&#xD;
(* Out: {{2019, 10, 1, 0, 0, 0.}, {2019, 7, 1, 0, 0, 0.}} *)&#xD;
&#xD;
DateRange[{2019, 7, 1}, {2019, 12, 5}, {3, &amp;#034;BeginningOfMonth&amp;#034;}]&#xD;
(* Out: {{2019, 7, 1, 0, 0, 0.}, {2019, 10, 1, 0, 0, 0.}} *)&#xD;
```&#xD;
&#xD;
## AbsoluteTime&#xD;
&#xD;
### 1. Handling `TimeObject`&#xD;
&#xD;
`AbsoluteTime` convert `TimeObject` by adding `Today` value, which I think could be counterintuitive when somebody wants to compare `AbsoluteTime` of two `TimeObject` which was applied in different days, should use `Mod[,86400]` first.&#xD;
&#xD;
```&#xD;
DateList@AbsoluteTime@TimeObject[]&#xD;
(* Out: {2021, 11, 13, 15, 42, 56.} *)&#xD;
```&#xD;
&#xD;
Why not return this result ( `cAbsoluteTime`):&#xD;
&#xD;
```&#xD;
{1, 1, 1, 15, 42, 56.}&#xD;
```&#xD;
&#xD;
## UnixTime&#xD;
&#xD;
### 1. Truncating sub-second precision:&#xD;
&#xD;
Why `UnixTime` does not have floating numbers to handle more accurate dates?&#xD;
&#xD;
```&#xD;
DecimalForm[UnixTime[{2021, 11, 12, 12, 30, 30.35}], 30]&#xD;
(* Out: 1636700430 *)&#xD;
```&#xD;
&#xD;
What it could be: `1636707630.35`.&#xD;
&#xD;
## DateObject&#xD;
&#xD;
### 1. Raise overlapping message for non-overlap inputs&#xD;
&#xD;
For years, before `812` and after `2989` equality of two consecutive days raise `Message` while `DateOverlapsQ` returning `False`:&#xD;
&#xD;
```&#xD;
DateObject[{-1, 1, 1}] == DateObject[{-1, 1, 2}]&#xD;
&#xD;
DateOverlapsQ[DateObject[{-1, 1, 1}], DateObject[{-1, 1, 2}]]&#xD;
(* Out: False *)&#xD;
&#xD;
DateOverlapsQ[DateObject[{-1, 1, 2}], DateObject[{-1, 1, 1}]]&#xD;
(* Out: False *)&#xD;
```&#xD;
&#xD;
![ERROR IMAGE](https://i.imgur.com/DMuEk69.jpg)&#xD;
&#xD;
Far future example:&#xD;
&#xD;
```&#xD;
DateObject[{2988, 10, 12}] == DateObject[{2988, 10, 13}]&#xD;
(* No Message, Out: False*)&#xD;
&#xD;
(* But *)&#xD;
DateObject[{2989, 10, 12}] == DateObject[{2989, 10, 13}]&#xD;
```&#xD;
&#xD;
![ERROR IMAGE](https://i.imgur.com/xLoEP5W.jpg)&#xD;
&#xD;
### 2. Suggestion - Round &amp;#039;Second&amp;#039; in `Second` granularity&#xD;
&#xD;
Is this considered `Second` granularity or `Sub-Second`/`Instant` granularity ?&#xD;
&#xD;
```&#xD;
DateObject[{2020, 1, 1, 30, 45, 12.25}, &amp;#034;Second&amp;#034;]&#xD;
(* Out: DateObject[List[2020,1,2,6,45,12.25`],&amp;#034;Second&amp;#034;,&amp;#034;Gregorian&amp;#034;,3.5`] *)&#xD;
```&#xD;
&#xD;
### 3. Incorrect result with AbsoluteTime values with custom granularity&#xD;
&#xD;
Consider date `{2020, 12, 10}` which is `Thursday` and every week starts on Monday (default option):&#xD;
&#xD;
```&#xD;
DateList@DateObject[3816547200, &amp;#034;Week&amp;#034;]&#xD;
(* Out: {2020, 12, 10, 0, 0, 0.} *)&#xD;
&#xD;
DateList@DateObject[DateList@3816547200, &amp;#034;Week&amp;#034;]&#xD;
(* Out: {2020, 12, 7, 0, 0, 0.} *)&#xD;
&#xD;
DateList@DateObject[FromAbsoluteTime@3816547200, &amp;#034;Week&amp;#034;]&#xD;
(* Out: {2020, 12, 7, 0, 0, 0.} *)&#xD;
```&#xD;
&#xD;
This also applies to `WeekBeginningSunday`, `Century`, `CenturyBeginning01`, `Millennium`, `MillenniumBeginning01`. &#xD;
&#xD;
&#xD;
## TimeObject&#xD;
&#xD;
### 1. Suggestion - Embed TimeZone offset to TimeObject like DateObject&#xD;
&#xD;
Since `DateObject` uses `$TimeZone` and can be manipulated in a session while `TimeObject` uses system clock, why not use the time-zone offset from the system ? (My system time-zone offset is +3.5)&#xD;
&#xD;
```&#xD;
First@TimeObject[]&#xD;
(* Out: {14, 4, 3.} *)&#xD;
&#xD;
First@TimeZoneConvert[TimeObject[], &amp;#034;GMT&amp;#034;]&#xD;
(* Out: {14, 4, 3.} *)&#xD;
&#xD;
First@TimeZoneConvert[TimeObject[TimeZone -&amp;gt; 3.5], &amp;#034;GMT&amp;#034;]&#xD;
(* Out: {10, 34, 3.} *)&#xD;
&#xD;
(* Real answer *)&#xD;
TimeZoneConvert[DateObject[], &amp;#034;GMT&amp;#034;][[1, -3 ;;]]&#xD;
(* Out: {10, 34, 3.} *)&#xD;
```&#xD;
&#xD;
## CalendarConvert&#xD;
&#xD;
### 1. Negative/Zero in the month!&#xD;
&#xD;
For far future years, conversion to `&amp;#034;AstronomicalPersian&amp;#034;` will give negative/zero months&#xD;
&#xD;
```&#xD;
First@CalendarConvert[DateObject@{9999997, 9, 24}, &amp;#034;AstronomicalPersian&amp;#034;]&#xD;
(* Out: {9999386, -15, 5} *)&#xD;
```&#xD;
&#xD;
Another example (wrong output probably starts from this year):&#xD;
&#xD;
```&#xD;
First@CalendarConvert[DateObject@{82380, 7, 4}, &amp;#034;AstronomicalPersian&amp;#034;]&#xD;
(* Out: {81758, 12, 29} *)&#xD;
&#xD;
First@CalendarConvert[DateObject@{82380, 7, 5}, &amp;#034;AstronomicalPersian&amp;#034;]&#xD;
(* Out: {81759, 0, 26} *)&#xD;
```&#xD;
&#xD;
If we don&amp;#039;t apply `First` to the `CalendarConvert` you&amp;#039;ll see:&#xD;
&#xD;
![ERROR IMAGE](https://i.imgur.com/MIe5Dmx.jpg)&#xD;
&#xD;
### 2. Two consecutive leap years in the Persian calendar&#xD;
&#xD;
Persian Calendar has a little complex leap year system, that&amp;#039;s why it has an `&amp;#034;ArithmeticPersian&amp;#034;` and `&amp;#034;AstronomicalPersian&amp;#034;` option in calendar conversion. `&amp;#034;AstronomicalPersian&amp;#034;` type is the more accurate system. I don&amp;#039;t think two consecutive leap years is correct.&#xD;
Also, I should mention, leap month in the `Persian` calendar is the 12th month which in normal years has 29 days, and leap years have 30 days.&#xD;
&#xD;
```&#xD;
First@CalendarConvert[DateObject@{622, 3, 21}, &amp;#034;AstronomicalPersian&amp;#034;]&#xD;
First@CalendarConvert[DateObject@{621, 3, 21}, &amp;#034;AstronomicalPersian&amp;#034;]&#xD;
```&#xD;
&#xD;
If we calculate with `cCalendarConvert`:&#xD;
&#xD;
```&#xD;
{-1, 12, 30, 0, 0, 0.}&#xD;
&#xD;
{-1, 1, 1, 0, 0, 0.}&#xD;
```&#xD;
&#xD;
## TimeZoneConvert&#xD;
&#xD;
### 1. Wrong result&#xD;
&#xD;
For version 13 live stream, I want to schedule to watch it live, but I live in a different time-zone, so I notice this strange case:&#xD;
&#xD;
First to show the real offset from my place to `New_York`:&#xD;
&#xD;
```&#xD;
TimeZoneOffset[&amp;#034;America/New_York&amp;#034;, &amp;#034;Asia/Tehran&amp;#034;, &#xD;
 DateObject[{2021, 12, 13, 15, 30}, TimeZone -&amp;gt; &amp;#034;America/New_York&amp;#034;]]&#xD;
(* Out: -8.5 *)&#xD;
```&#xD;
&#xD;
Now, with `8.5` hour offset, convert the date to the Persian calendar, then convert time zones:&#xD;
&#xD;
```&#xD;
First@TimeZoneConvert[&#xD;
  CalendarConvert[&#xD;
   DateObject[{2021, 12, 13, 15, 30}, TimeZone -&amp;gt; &amp;#034;America/New_York&amp;#034;],&#xD;
    &amp;#034;AstronomicalPersian&amp;#034;], &amp;#034;Asia/Tehran&amp;#034;]&#xD;
&#xD;
(* Out: {1400, 9, 22, 23, 51} *)&#xD;
```&#xD;
&#xD;
We get `8h 21m` offset!&#xD;
&#xD;
Further investigation, shows that the offset used in the calculation may differ from the real one:&#xD;
&#xD;
```&#xD;
First@TimeZoneConvert[&#xD;
  DateObject[{1400, 9, 22, 3, 31, 15}, &#xD;
   CalendarType -&amp;gt; &amp;#034;AstronomicalPersian&amp;#034;], &amp;#034;Europe/London&amp;#034;]&#xD;
&#xD;
(* Out: {1400, 9, 22, 0, 0, 0.} *)&#xD;
```&#xD;
&#xD;
If we change the destination to `GMT` the correct result shows up:&#xD;
&#xD;
```&#xD;
First@TimeZoneConvert[&#xD;
  DateObject[{1400, 9, 22, 3, 30, 0}, &#xD;
   CalendarType -&amp;gt; &amp;#034;AstronomicalPersian&amp;#034;], &amp;#034;GMT&amp;#034;]&#xD;
&#xD;
(* Out: {1400, 9, 22, 0, 0, 0.} *)&#xD;
```&#xD;
&#xD;
# Bonus&#xD;
&#xD;
If you have read this far, congratulations. These functions were absent in wolfram but are useful to have, so here you are:&#xD;
&#xD;
## cHolidayName&#xD;
&#xD;
For getting the name of a holiday:&#xD;
&#xD;
```&#xD;
cHolidayName[{2021, 11, 25}]&#xD;
(* Out: &amp;#034;Thanksgiving Day&amp;#034; *)&#xD;
```&#xD;
&#xD;
Observed Holidays, the original day is not considered a holiday:&#xD;
&#xD;
```&#xD;
cHolidayName[{2021, 7, 5}]&#xD;
(* Out: &amp;#034;Independence Day&amp;#039; day off&amp;#034; *)&#xD;
&#xD;
cHolidayName[{2021, 7, 4}]&#xD;
(* Out: Missing[&amp;#034;Holiday&amp;#034;] *)&#xD;
```&#xD;
&#xD;
Also if you&amp;#039;re more interested in holidays, there are two related internal functions for getting next/previous holiday:&#xD;
&#xD;
```&#xD;
DateList@cDateFunctions`Private`cNextHoliday[{2021, 11, 12}]&#xD;
(* Out: {2021, 11, 25, 0, 0, 0.} *)&#xD;
&#xD;
DateList@cDateFunctions`Private`cPreviousHoliday[{2021, 11, 12}]&#xD;
(* Out: {2021, 11, 11, 0, 0, 0.} *)&#xD;
```&#xD;
&#xD;
Also for getting the previous holiday, there is a lower limit:&#xD;
&#xD;
```&#xD;
cDateFunctions`Private`cPreviousHoliday[{1500, 11, 11}]&#xD;
&#xD;
(* Message: &amp;#034;No official holiday exists before 1863-11-26.&amp;#034; *)&#xD;
```&#xD;
&#xD;
## cCalendarView&#xD;
&#xD;
For getting a month/multiple month/custom range calendar views with `Grid` which supports highlighting and is only for `&amp;#034;Gregorian&amp;#034;` calendar (See Advance section for other calendars):&#xD;
&#xD;
### View a month at a glance:&#xD;
&#xD;
```&#xD;
cCalendarView[{2021, 11}]&#xD;
```&#xD;
&#xD;
![CALENDAR VIEW](https://i.imgur.com/8HKZmzl.jpg)&#xD;
&#xD;
```&#xD;
cCalendarView[{2021, 11}, {2021, 11, 12} -&amp;gt; Red]&#xD;
```&#xD;
&#xD;
![CALENDAR VIEW](https://i.imgur.com/eUnjfHW.jpg)&#xD;
&#xD;
```&#xD;
cCalendarView[{2021, 11}, 12 ;; 15]&#xD;
```&#xD;
&#xD;
![CALENDAR VIEW](https://i.imgur.com/6ST9RCA.jpg)&#xD;
&#xD;
```&#xD;
cCalendarView[{2021, 11}, {6, 7} ;; ;; 7]&#xD;
```&#xD;
&#xD;
![CALENDAR VIEW](https://i.imgur.com/cQEquZR.jpg)&#xD;
&#xD;
```&#xD;
cCalendarView[{2021, 11}, &amp;#034;Holiday&amp;#034;]&#xD;
```&#xD;
&#xD;
![CALENDAR VIEW](https://i.imgur.com/blCVoeA.jpg)&#xD;
&#xD;
Use `cCalendarMultipleView` to view multiple months in a row. Could be positive or negative:&#xD;
&#xD;
```&#xD;
(* show 2021-11 and 1 month after that with highlighting *)&#xD;
cCalendarMultipleView[{2021, 11}, 1, 6 ;; ;; 6]&#xD;
```&#xD;
&#xD;
![CALENDAR VIEW](https://i.imgur.com/15Ud7MH.jpg)&#xD;
&#xD;
Use `cCalendarRangeView` to view a range:&#xD;
&#xD;
```&#xD;
cCalendarRangeView[{2021, 11}, {2021,12},&#xD;
   {{{2021, 11, 14}, {2021, 11, 15}, {2021, 11, 16}} -&amp;gt; Gray,&#xD;
    {2021, 11, 13} -&amp;gt; Green}]&#xD;
```&#xD;
&#xD;
![CALENDAR VIEW](https://i.imgur.com/d9aHHeh.jpg)&#xD;
&#xD;
Note that `cCalendarMultipleView` and `cCalendarRangeView` automatically highlight the first day of each month.&#xD;
&#xD;
## Suggestion - N-th Weekday&#xD;
&#xD;
How should we program to express 4th Thursday (for Thanksgiving ) / last Monday (for Memorial Day) ?&#xD;
Here is my proposal inspired by the `C++ Chrono` library, implemented via `UpValues` (minimum viable product):&#xD;
&#xD;
```&#xD;
(Unprotect[#];&#xD;
    UpValues[#] = {};&#xD;
    # /: {year_Integer, month_Integer, #[n_Integer?Positive]} := DatePlus[{year, month, 0}, {n, #}];&#xD;
    # /: {year_Integer, month_Integer, #[n_Integer?Negative]} := DatePlus[{year, month + 1, 1}, {n, #}];&#xD;
    # /: {year_Integer, month_Integer, #[First]} := DatePlus[{year, month, 0}, {1, #}];&#xD;
    # /: {year_Integer, month_Integer, #[Last]} := DatePlus[{year, month + 1, 1}, {-1, #}];&#xD;
    Protected[#];) &amp;amp; /@ {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};&#xD;
```&#xD;
&#xD;
Now, we can use it anywhere (should be fixed):&#xD;
&#xD;
```&#xD;
{2021, 11, Thursday[4]}&#xD;
(* Out: {2021, 11, 25} *)&#xD;
&#xD;
{2021, 5, Monday[Last]}&#xD;
(* Out: {2021, 5, 31} *)&#xD;
&#xD;
AbsoluteTime[{2021, 5, Monday[Last]}]&#xD;
(* Out: 3831408000 *)&#xD;
&#xD;
(* Second to last friday *)&#xD;
{2021, 12, Friday[-2]}&#xD;
(* Out: {2021, 12, 24} *)&#xD;
```&#xD;
&#xD;
Limiting UpValues to date functions only and supporting month names, would greatly improve functionality and readability.&#xD;
&#xD;
# For Advanced Users&#xD;
&#xD;
This journey of rewriting date functions in wolfram as joyful and teachable as it was, was ending and after looking at my code, I notice in many places, `DateList` and `AbsoluteTime` were used many times, I thought, if I could make them faster, the whole package could benefit this speed up. In many parts, I reached my goal but I didn&amp;#039;t test the performance gained from switching.&#xD;
&#xD;
Since these functions are Kernel-Level functions (probably written in `C` language), Wolfram Language is not the right tool to compete, so I choose Rust. You could read about its benefits and guarantees over `C` on other sites. Here you&amp;#039;ll see the comparison. `C` language is still used as the interface for Rust functions. (If you have a better solution, I&amp;#039;m more than happy to hear about Rust integration.)&#xD;
&#xD;
This journey just like the previous one doesn&amp;#039;t end with `DateList` and `AbsoluteTime`, but it also came with writing 3 calendars (`&amp;#034;Greogiran&amp;#034;`, `&amp;#034;ArithmeticPersian&amp;#034;` with 5 method, `AstronomicalPersian`, `&amp;#034;Islamic&amp;#034;` which is a civil arithmetic calendar, with 4 method). For additional options they support, visit the [Github Page](https://github.com/ben-izd/cDateFunctions).&#xD;
&#xD;
## Installation&#xD;
&#xD;
For testing this section, you need to follow the [Github](https://github.com/ben-izd/cDateFunctions) instructions.&#xD;
&#xD;
## `AbsoluteTime` / `FromAbsoluteTime`&#xD;
&#xD;
`cAbsoluteTime` is on average **0.9 times slower** than `AbsoluteTime` over 1,000,000 random `DateList`.&#xD;
&#xD;
`cAbsoluteTime` is on average the **2 times faster** as `AbsoluteTime` over 100,000 random `DateObject`.&#xD;
&#xD;
If we call `AbsoluteTime` to get the current value without any argument,&#xD;
`cAbsoluteTime` is on average **42 times faster** than `AbsoluteTime` while having **6 times lower** memory usage.&#xD;
&#xD;
`cFromAbsoluteTime` on the other hand is **1.5 times faster** than `FromAbsoluteTime` over 100,000 random real, which could be faster considering creating a `DateObject` overhead (see Comparing Internals section).&#xD;
&#xD;
&#xD;
Also unlike Mathematica, `cAbsoluteTime` does support other calendars:&#xD;
&#xD;
```&#xD;
cDateList@cAbsoluteTime[{1400, 7, 20}, CalendarType -&amp;gt; &amp;#034;ArithmeticPersian&amp;#034;]&#xD;
(* Out: {2021, 10, 12, 0, 0, 0} *)&#xD;
&#xD;
cDateList@cAbsoluteTime[{1443, 3, 5}, CalendarType -&amp;gt; &amp;#034;Islamic&amp;#034;]&#xD;
(* Out: {2021, 10, 12, 0, 0, 0} *)&#xD;
```&#xD;
&#xD;
&#xD;
## `DateList`&#xD;
&#xD;
`cDateList` is on average **~1.7 times faster** than `DateList` over 1,000,000 random numbers (`Real`/`Integer`).&#xD;
&#xD;
`cDateList` is on average **~1.9 times faster** than `DateList` over 1,000,000 random un-normal `DateList`.&#xD;
&#xD;
## `CalendarConvert`&#xD;
&#xD;
All the numbers come from testing 10,000 random samples.&#xD;
&#xD;
In `&amp;#034;Gregorian&amp;#034;` to `&amp;#034;ArithmeticPersian&amp;#034;`\&#xD;
`cCalendarConvert` is on average **16 times faster** than `CalendarConvert`.&#xD;
&#xD;
In `&amp;#034;Gregorian&amp;#034;` to `&amp;#034;AstronomicalPersian&amp;#034;`\&#xD;
`cCalendarConvert` is on average **140 times faster** than `CalendarConvert`.&#xD;
&#xD;
In `&amp;#034;Gregorian&amp;#034;` to `&amp;#034;Islamic&amp;#034;`\&#xD;
`cCalendarConvert` is on average **9 times faster** than `CalendarConvert`.&#xD;
&#xD;
In `&amp;#034;Islamic&amp;#034;` to `&amp;#034;ArithmeticPersian&amp;#034;`\&#xD;
`cCalendarConvert` is on average **19 times faster** than `CalendarConvert`.&#xD;
&#xD;
`&amp;#034;AstronomicalPersian&amp;#034;` uses an algorithm introduced by Edward M. Reingold, Nachum Dershowitz in their book, &amp;#034;Calendrical Calculations: The Ultimate Edition&amp;#034;. It was implemented to perform the test but because of its license, it&amp;#039;s not included in the source code until I get approval from the author (the source is commented in the interface code).&#xD;
&#xD;
Since both `&amp;#034;Islamic&amp;#034;` and `&amp;#034;ArithmeticPersian&amp;#034;` have methods to use, converting one to another while using `Method` option, input `Method` will be used for the output format and input will be converted using the default method, if you want more control, first convert it to `&amp;#034;Gregorian&amp;#034;`, then convert it to your specified calendar.&#xD;
&#xD;
## `LeapYearQ`&#xD;
&#xD;
Because of different methods of calculations, this `LeapYearQ` uses kernel-level functions (instead of pure wolfram language shown earlier, which will be overridden) to handle 3 calendars. Tests were done on over 100,000 random samples.&#xD;
&#xD;
`&amp;#034;Gregorian&amp;#034;`\&#xD;
`cLeapYearQ` is on average **8 times faster** than `LeapYearQ`.&#xD;
&#xD;
`&amp;#034;ArithmeticPersian&amp;#034;`\&#xD;
`cLeapYearQ` is on average **9 times faster** than `LeapYearQ` (as discussed earlier, `LeapYearQ` gives the wrong result for this type of calendar).&#xD;
&#xD;
`&amp;#034;AstronomicalPersian&amp;#034;`\&#xD;
`cLeapYearQ` is on average **102 times faster** than `LeapYearQ`.&#xD;
&#xD;
`&amp;#034;Islamic&amp;#034;`\&#xD;
`cLeapYearQ` is on average **6 times faster** than `LeapYearQ`.&#xD;
&#xD;
And remember in `cLeapYearQ`  with `&amp;#034;ArithmeticPersian&amp;#034;` and `&amp;#034;Islamic&amp;#034;`, you can choose different methods of leap-year calculation, visit [Github](https://github.com/ben-izd/cDateFunctions) for more information.&#xD;
&#xD;
&#xD;
## `JulianDate` / `FromJulianDate`&#xD;
&#xD;
`cJulianDate` is on average **3 times faster** than `JulianDate` over 10,000 random `DateList`.&#xD;
&#xD;
`cFromJulianDate` is on average **1.8 times faster** than `FromJulianDate` over 100,000 real, actually, it&amp;#039;s faster than stated, creating a `DateObject` takes most of the time.&#xD;
&#xD;
## `UnixTime` / `FromUnixTime`&#xD;
&#xD;
`cUnixTime` is on average **7 times faster** than `UnixTime` over 100,000 random `DateList` samples.&#xD;
&#xD;
`cFromUnixTime` is on average **2 times faster** than `FromUnixTime` but it shares the same problem as `cFromJulianDate`. &#xD;
&#xD;
&#xD;
## `cMonthView` / `cPartialView`&#xD;
&#xD;
With access to these calendars and different methods of calculation, it was the best opportunity to create a function that prints month/year view.&#xD;
&#xD;
See 2021 calendar at a glance:&#xD;
&#xD;
![YEAR_IMAGE](https://i.imgur.com/XeCgSNQ.jpg)&#xD;
&#xD;
or other calendars (use `CalendarType`)&#xD;
&#xD;
![OTHER_YEAR_IMAEG](https://i.imgur.com/nUHgbi5.jpg)&#xD;
&#xD;
Unlike earlier `cMonthView` it does not support highlighting yet.&#xD;
For printing a range/month continuously use `cPartialView` which accepts a start and end date.&#xD;
&#xD;
Wolfram technology conference  at a glance (with manually highlighting):&#xD;
&#xD;
```&#xD;
MapAt[Highlighted, &#xD;
 cPartialView[{2021, 11, 7}, {2021, 11, 20}], {{1, 1, 1, 6 ;; 7}, {1, &#xD;
   1, 2, 1 ;; 2}}]&#xD;
```&#xD;
&#xD;
![cPartialView_IMAGE](https://i.imgur.com/gGkO3qH.jpg)&#xD;
&#xD;
# Limitations&#xD;
&#xD;
Since all these functions are written in low-level and should support `C` types, not arbitrary precision that Wolfram-Language has (although Wolfram has its own limitation, like rounding error).&#xD;
&#xD;
## `cAbsoluteTime`:&#xD;
&#xD;
 `cAbsoluteTime` has a limit, going further will not raise any error but cause overflow (wrap around).&#xD;
&#xD;
```&#xD;
(* max date - second is not important *)&#xD;
cAbsoluteTime[{292277026526, 12, 5, 15, 30}]&#xD;
(* Out: 9223372036854720000 *)&#xD;
&#xD;
(* going further lead to overflow *)&#xD;
cAbsoluteTime[{292277026526, 12, 5, 15, 31}]&#xD;
(* Out: -9223372036854775756 *)&#xD;
&#xD;
(* min date*)&#xD;
cAbsoluteTime[{-292277022728, 1, 27, 0, 0, 0}]&#xD;
(* Out: -9223372036854720000 *)&#xD;
&#xD;
(* going further lead to overflow *)&#xD;
cAbsoluteTime[{-292277022728, 1, 26, 0, 0, 0}]&#xD;
(* Out: 9223372036854745216 *)&#xD;
```&#xD;
&#xD;
## `cDateList`:&#xD;
&#xD;
Unlike `cAbsoluteTime` which crossing the limit will not raise any error, here Mathematica will raise an error because it can not convert numbers greater than `2^63-1` to machine size 64-bit integers. But because of some internal design decisions, the safe range is shifted towards the negative side. So there is also a range before `2^63-1`, which doesn&amp;#039;t raise any error but leads to overflow. (We&amp;#039;re discussing around year `292,277,024,627`, which if you&amp;#039;re interested, I&amp;#039;ll add more details.) &#xD;
&#xD;
This pattern also applies to other kernel-level functions.&#xD;
&#xD;
# Comparing `Internal`s&#xD;
&#xD;
In the built-in `Internal` context, there are three functions that do the `DateList` functionalities separately:&#xD;
&#xD;
- `DateListToDateList`&#xD;
&#xD;
- `DateListToSeconds`&#xD;
&#xD;
- `SecondsToDateList`&#xD;
&#xD;
Like Mathematica, c\* functions also have kernel-level functions to call but there is a caveat. Since passing arrays to/from `C` language (interface), should be a single type, I couldn&amp;#039;t find an easy way to handle `DateList` mix-type arrays beside `WSTP` (second could be Real, `LibraryLink` developers, if you&amp;#039;re reading, I&amp;#039;m waiting for integration of `TypeProduct` to use structs), so these kernel functions only support maximum 5 elements as input/output (`{Y,M,D,H,M}`, second will be calculated in the interface, not in the kernel part).&#xD;
&#xD;
Comparing Mathematica `Internal` with `cDateFunctions` &amp;gt; `LibraryLink` over random 1,000,000 samples without considering second (`Internal` support second but not `cDatefunctions Kernel`):&#xD;
&#xD;
`DateListToSecond` (`AbsoluteTime`):&#xD;
`LibraryLink` is on average **0.7 times slower** than `Internal`.&#xD;
&#xD;
`SecondToDateList` (`DateList`):&#xD;
`LibraryLink` is on average **0.8 times faster** than `Internal`.&#xD;
&#xD;
`DateListToDateList`:&#xD;
`LibraryLink` is on average **1.12 times faster** than `Internal`.&#xD;
&#xD;
Calling raw `LibraryLink` outperforms the internals but input/output doesn&amp;#039;t include second, the result shown above came from calling the simplest interface. (For those curious people, calling raw interface is on average **8, 7, 9 times faster** respectively).&#xD;
&#xD;
As discussed, `cDateFunctions`\``LibraryLink` is fast but the reason that their interface is not as fast as their kernel, is mainly because of the pattern matching (to support `CalendarType` and `Method`) and second calculation.&#xD;
&#xD;
&#xD;
# Final note &#xD;
&#xD;
For those who are interested in calendars and their implementations, I recommend &amp;#034;Calendrical Calculation&amp;#034; by Edward M. Reingold, Nachum Dershowitz which I think the Wolfram/Microsoft team has seen this book because of some similarities I noticed in their sources. Both book&amp;#039;s authors and developer teams did a great job which is appreciated (Microsoft: .Net). The book also comes with a source file in `Lisp` language. The implementation of `cCalendarConvert` `&amp;#034;AstronomicalPersian&amp;#034;` is ported from this book.&#xD;
&#xD;
&#xD;
Because of my limited time, I did cover 4 calendars and introduced different methods of calculation to cover different needs and you should know both `&amp;#034;Persian&amp;#034;` and `&amp;#034;Islamic&amp;#034;` in some countries use observation not algorithms to determine leap year/month length.&#xD;
&#xD;
The Rust code has a framework within, to support other calendars with similar characteristics as Gregorian and ... , with providing months length and two functions for checking and counting leap years and some little details, you&amp;#039;ll have `AbsoluteTime` and `DateList` engine + `Month/YearView` (currently for 12 months calendars) for your calendar for free.&#xD;
&#xD;
`&amp;#034;ArithmeticPersian&amp;#034;` and `&amp;#034;Islamic&amp;#034;` also use frameworks, so for any future changes in their leap year calculations that follow the old structure, you can add them as a new method under 20 lines of code.&#xD;
&#xD;
Improving is a never-ending process. For me, I reached beyond the main goal I set for myself, of course, there were a lot of moments which I was so close to abandoning the project, especially when I was figuring out how `LibraryLink` works and build the project without compiling errors but looking back, it&amp;#039;s worth it and I feel more powerful than before. I hope you learn something and if you had any questions/comments/suggestions, feel free to add them.</description>
    <dc:creator>Benjamin Izadpanah</dc:creator>
    <dc:date>2022-01-01T06:44:51Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1057588">
    <title>Parallel Mathematica Environment on the RaspberryPi using OOP</title>
    <link>https://community.wolfram.com/groups/-/m/t/1057588</link>
    <description>My project, Parallel Mathematica Environment on the RaspberryPi using OOP, is a sample application of **Object Oriented Programming for the Mathematica** cluster computing, implemented with a Mac and three RaspberryPi Zero connected with a USB hub and three USB cables.&#xD;
&#xD;
Basic idea is to deploy a constructed instance image to calculating servers (RaspberryPi) and send messages to the instance. [OOP on the Mathematica is already developed and shown][1] in this community, and further detail is shown on [slidesshare][2] titled of &amp;#034;OOP for Mathematica.&amp;#034;&#xD;
![enter image description here][3]&#xD;
&#xD;
&#xD;
----------&#xD;
&#xD;
&#xD;
&#xD;
Preparing for RaspberryPi Zero is as follows using SSH connection from a Mac, &#xD;
&#xD;
 - naming each Zero as raspberypi,raspberrypi1,raspberrypi2,...&#xD;
 - set the server program &amp;#034;init&amp;#034; to each RaspberryPi, init is,&#xD;
&#xD;
        $ cat init&#xD;
        While[True,&#xD;
        Run[nc -l 8000&amp;gt;input];&#xD;
        temp=ReleaseHold[&amp;lt;&amp;lt;input];&#xD;
        temp &amp;gt;&amp;gt;output;&#xD;
        Run[nc your-mac-hostname.local 8002&amp;lt;output]&#xD;
        ]&#xD;
        &#xD;
&#xD;
where, socket numbers must be identical.&#xD;
&#xD;
 - Run Mathematica manually, and wait the booting Mathematica up.&#xD;
&#xD;
        $ wolfram &amp;lt;init&amp;amp;&#xD;
&#xD;
Checking each RaspberryPi is useful as,&#xD;
&#xD;
    $ nc -l 8002 &amp;gt;output|nc raspberrypi.local 8000 &amp;lt;&amp;lt;EOF&#xD;
    &amp;gt; 10!&#xD;
    &amp;gt; EOF&#xD;
    $ cat output&#xD;
    3628800&#xD;
&#xD;
&#xD;
----------&#xD;
&#xD;
Cluster controller program on a Mac is,&#xD;
&#xD;
 - set directory&#xD;
&#xD;
        SetDirectory[NotebookDirectory[]];&#xD;
&#xD;
 - setup socket communication process&#xD;
&#xD;
        com1=&amp;#034;nc -l 8002 &amp;gt;output1 |nc raspberrypi.local 8000 &amp;lt;input1&amp;#034;;&#xD;
        com2=&amp;#034;nc -l 9002 &amp;gt;output2 |nc raspberrypi1.local 9000 &amp;lt;input2&amp;#034;;&#xD;
        com3=&amp;#034;nc -l 9502 &amp;gt;output3 |nc raspberrypi2.local 9500 &amp;lt;input3&amp;#034;;&#xD;
&#xD;
 - set object property&#xD;
&#xD;
        obj={&#xD;
           &amp;lt;|&amp;#034;name&amp;#034;-&amp;gt;node1,&amp;#034;comm&amp;#034;-&amp;gt;com1,&amp;#034;in&amp;#034;-&amp;gt;&amp;#034;input1&amp;#034;,&amp;#034;out&amp;#034;-&amp;gt;&amp;#034;output1&amp;#034;,&amp;#034;p&amp;#034;-&amp;gt;{2000,3500}|&amp;gt;,&#xD;
           &amp;lt;|&amp;#034;name&amp;#034;-&amp;gt;node2,&amp;#034;comm&amp;#034;-&amp;gt;com2,&amp;#034;in&amp;#034;-&amp;gt;&amp;#034;input2&amp;#034;,&amp;#034;out&amp;#034;-&amp;gt;&amp;#034;output2&amp;#034;,&amp;#034;p&amp;#034;-&amp;gt;{3501,4000}|&amp;gt;,&#xD;
           &amp;lt;|&amp;#034;name&amp;#034;-&amp;gt;node3,&amp;#034;comm&amp;#034;-&amp;gt;com3,&amp;#034;in&amp;#034;-&amp;gt;&amp;#034;input3&amp;#034;,&amp;#034;out&amp;#034;-&amp;gt;&amp;#034;output3&amp;#034;,&amp;#034;p&amp;#034;-&amp;gt;{4000,4500}|&amp;gt;};&#xD;
&#xD;
 - define calculation server class, where is a sample Mersenne prime number calculation&#xD;
&#xD;
        new[nam_]:=Module[{ps,pe},&#xD;
           mersenneQ[n_]:=PrimeQ[2^n-1];&#xD;
           setv[nam[{s_,e_}]]^:={ps,pe}={s,e};&#xD;
           calc[nam]^:=Select[Range[ps,pe],mersenneQ]&#xD;
           ];&#xD;
&#xD;
 - construct instances&#xD;
&#xD;
        Map[new[#name]&amp;amp;,obj];&#xD;
&#xD;
 - deploy instances to calculation servers&#xD;
&#xD;
        Map[Save[#in,#name]&amp;amp;,obj];&#xD;
        Map[Run[#comm]&amp;amp;,obj];&#xD;
&#xD;
 - send message to each instance&#xD;
&#xD;
        Map[Put[Hold@setv[#name[#p]],#in]&amp;amp;,obj];&#xD;
        Map[Run[#comm]&amp;amp;,obj];&#xD;
&#xD;
 - start calculation&#xD;
&#xD;
        Map[Put[Hold@calc[#name],#in]&amp;amp;,obj];&#xD;
        proc=Map[StartProcess[{$SystemShell,&amp;#034;-c&amp;#034;,#comm}]&amp;amp;,obj]&#xD;
&#xD;
 - wait for the process termination (mannualy in this sample code)&#xD;
&#xD;
        Map[ProcessStatus[#]&amp;amp;,proc]&#xD;
         {Finished,Finished,Finished}&#xD;
&#xD;
 - gather the results&#xD;
&#xD;
        Map[FilePrint[#out]&amp;amp;,obj];&#xD;
         {2203, 2281, 3217}&#xD;
        {}&#xD;
        {4253, 4423}&#xD;
&#xD;
&#xD;
  [1]: http://community.wolfram.com/groups/-/m/t/897081?p_p_auth=o5qxZhNR&#xD;
  [2]: https://www.slideshare.net/kobayashikorio/oop-for-mathematica&#xD;
  [3]: http://community.wolfram.com//c/portal/getImageAttachment?filename=2017-04-10.jpg&amp;amp;userId=897049</description>
    <dc:creator>Hirokazu Kobayashi</dc:creator>
    <dc:date>2017-04-10T01:15:22Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/2516662">
    <title>Re-exploring the structure of Chinese character images</title>
    <link>https://community.wolfram.com/groups/-/m/t/2516662</link>
    <description>&amp;amp;[Wolfram Notebook][1]&#xD;
&#xD;
&#xD;
  [1]: https://www.wolframcloud.com/obj/afc17dcc-20ac-4990-a933-02fed606f0af</description>
    <dc:creator>Anton Antonov</dc:creator>
    <dc:date>2022-04-22T17:14:10Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/3082695">
    <title>Making Lego Art from Images</title>
    <link>https://community.wolfram.com/groups/-/m/t/3082695</link>
    <description>![enter image description here][1]&#xD;
&#xD;
&amp;amp;[Wolfram Notebook][2]&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=Heroimage.gif&amp;amp;userId=20103&#xD;
  [2]: https://www.wolframcloud.com/obj/3e0cfefc-7168-4b87-87b7-554df0aa62c5</description>
    <dc:creator>Kotaro Okazaki</dc:creator>
    <dc:date>2023-12-13T13:45:49Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/3725603">
    <title>Filling Mars with water: Martian dichotomy and oceans versus continents at Earth&amp;#039;s 71% water surface</title>
    <link>https://community.wolfram.com/groups/-/m/t/3725603</link>
    <description>[![Filling Mars with water: Martian dichotomy and oceans versus continents at Earth&amp;#039;s 71% water surface][1]][2]&#xD;
&#xD;
&amp;amp;[Wolfram Notebook][3]&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=sdsfswae.jpg&amp;amp;userId=11733&#xD;
  [2]: https://community.wolfram.com//c/portal/getImageAttachment?filename=sdsfswae.jpg&amp;amp;userId=11733&#xD;
  [3]: https://www.wolframcloud.com/obj/9c752467-44a5-4184-a280-22a6dbf960a8</description>
    <dc:creator>Vitaliy Kaurov</dc:creator>
    <dc:date>2026-06-02T04:19:42Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/2961701">
    <title>Lucky Palindromes: when do prime factors of palindromes make palindromes?</title>
    <link>https://community.wolfram.com/groups/-/m/t/2961701</link>
    <description>[![enter image description here][1]][2]&#xD;
&#xD;
&amp;amp;[Wolfram Notebook][3]&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=43t45h545qerfgvfdsfh.jpg&amp;amp;userId=11733&#xD;
  [2]: https://community.wolfram.com//c/portal/getImageAttachment?filename=43t45h545qerfgvfdsfh.jpg&amp;amp;userId=11733&#xD;
  [3]: https://www.wolframcloud.com/obj/ec0d857e-09b2-4862-87b8-0d0c23869f69</description>
    <dc:creator>Vitaliy Kaurov</dc:creator>
    <dc:date>2023-07-13T17:19:37Z</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/2429964">
    <title>About Mathematica&amp;#039;s GPU roadmap</title>
    <link>https://community.wolfram.com/groups/-/m/t/2429964</link>
    <description>World&amp;#039;s computation is gradually switching to GPUs and other SIMD devices, and if Mathematica doesn&amp;#039;t adapt, it&amp;#039;ll end up cornered as a tool for toy computations. Are there plans to make it easy to use GPUs in Mathematica?&#xD;
&#xD;
You can see the reason for this in the graph below&#xD;
![enter image description here][1]&#xD;
&#xD;
2006 witnessed the death of Dennard scaling and since them, much of new performance growth went into parallel computation rather than sequential. You can now buy a gaming card RTX 3090 with 36 teraflops of computation, compared to [something like](https://bioinfo.lifl.fr/yass/iedera_dominance/boinc_cpu_list_additional.html) 200 gigaflops for CPU, and the gap is growing. These SIMD flops have gotten so cheap, that companies like Google are giving them out for free ([https://colab.research.google.com/](colab) runs things for free on a low-end GPU)&#xD;
&#xD;
As a concrete example is this [issue](https://mathematica.stackexchange.com/questions/261012/optimizing-sequential-computation). I couldn&amp;#039;t find an easy way to move this computation to GPU so had to reimplement it in Python. The changes you need to switch from CPU to GPU are [minimal](https://colab.research.google.com/drive/1rX78CmRkZJFAvzzyY8nS__H--1GvDky2#scrollTo=javoz9t7FAMu) in modern numpy-like frameworks (ie, Jax, CuPY, PyTorch): add &amp;#034;.cuda()&amp;#034; in front of some tensors and their computations are automatically on GPU.&#xD;
&#xD;
Mathematica could use similar approach to gradually enter the realm of user-friendly GPU computation -- first add an operation to move an array to GPU and back, and then implement GPU version of operation for the most common operations (matrix multiply), then gradually expand to more operations requested by users.&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2021-12-21at4.12.13PM.png&amp;amp;userId=1046145</description>
    <dc:creator>Yaroslav Bulatov</dc:creator>
    <dc:date>2021-12-22T00:28:20Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/3062083">
    <title>[GiF] ℘&amp;#039; (Conformal transformation of hexagonal grid)</title>
    <link>https://community.wolfram.com/groups/-/m/t/3062083</link>
    <description>![Conformal transformation of hexagonal grid][1]&#xD;
&#xD;
&amp;amp;[Wolfram Notebook][2]&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=plane36r.gif&amp;amp;userId=610054&#xD;
  [2]: https://www.wolframcloud.com/obj/1a895dac-598e-4187-baa0-ea87e5c163e2</description>
    <dc:creator>Clayton Shonkwiler</dc:creator>
    <dc:date>2023-11-08T18:00:47Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/2932299">
    <title>Glam-ifying 3D graphics: simple video animations and techniques</title>
    <link>https://community.wolfram.com/groups/-/m/t/2932299</link>
    <description>![enter image description here][1]&#xD;
&#xD;
&amp;amp;[Wolfram Notebook][2]&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=Glam-ifying3DGraphicsSimpleVideoAnimationsandTechniques.gif&amp;amp;userId=20103&#xD;
  [2]: https://www.wolframcloud.com/obj/cce345b0-10b4-49ec-b233-219984d53fce</description>
    <dc:creator>Anika Patel</dc:creator>
    <dc:date>2023-06-07T18:27:09Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/2510803">
    <title>[ART] An infinite amount of wolves: chaos game with an exclusion region</title>
    <link>https://community.wolfram.com/groups/-/m/t/2510803</link>
    <description>*MODERATOR NOTE: a submission to computations art contest, see more:* https://wolfr.am/CompArt-22&#xD;
&#xD;
----------&#xD;
&#xD;
![enter image description here][1]&#xD;
&#xD;
&amp;amp;[Wolfram Notebook][2]&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=WolfFractal.jpg&amp;amp;userId=20103&#xD;
  [2]: https://www.wolframcloud.com/obj/c862eb6d-895d-489a-a4bb-2b3362f3b033</description>
    <dc:creator>Sander Huisman</dc:creator>
    <dc:date>2022-04-14T21:59:45Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/2472460">
    <title>[GiF] Why is there no green starlight?</title>
    <link>https://community.wolfram.com/groups/-/m/t/2472460</link>
    <description>*MODERATOR NOTE: a submission to computations art contest, see more:* https://wolfr.am/CompArt-22&#xD;
&#xD;
![enter image description here][1]&#xD;
&#xD;
&amp;amp;[Wolfram Notebook][2]&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=test2_15_2_22.gif&amp;amp;userId=20103&#xD;
  [2]: https://www.wolframcloud.com/obj/a17f36f5-1294-41f4-87c2-6f5cb188d12f</description>
    <dc:creator>Ben Bartlett</dc:creator>
    <dc:date>2022-02-15T17:50:34Z</dc:date>
  </item>
  <item rdf:about="https://community.wolfram.com/groups/-/m/t/1927307">
    <title>Abelian Sandpile Model Simulation with C++ and LTemplate</title>
    <link>https://community.wolfram.com/groups/-/m/t/1927307</link>
    <description>![demo][1]&#xD;
&#xD;
##Abelian Sandpile Model##&#xD;
&#xD;
We call this Mathematica function to retrieve some background information from Wiki page: `WikipediaData[&amp;#034;Abelian sandpile model&amp;#034;]`&#xD;
&#xD;
&amp;gt; The Abelian sandpile model, also known as the Bak\[Dash]Tang\[Dash]Wiesenfeld model, was the first discovered example of a dynamical system displaying self-organized criticality.  It was introduced by Per Bak, Chao Tang and Kurt Wiesenfeld in a 1987 paper.The model is a cellular automaton. &#xD;
&#xD;
Also [in NKS][2] there is discussion about self-organized criticality and some simple demo codes in Mathematica. You may also find [this Numberhile video][3] on this topic interesting, typically it talks about where &amp;#034;Abelian&amp;#034; comes from based on group theory point of view.&#xD;
&#xD;
[![note][4]](https://www.wolframscience.com/nks/notes-7-9--self-organized-criticality/)&#xD;
&#xD;
I found [a GitHub repo][5] with a nice implementation of the model in C++ and it works quite well for large number ( ~ 1 million initial sand particles at origin). I think this can be a good example to show how to use `LTemplate` package to call this C++ package from Mathematica if you do not want to start from scratch using the basic LibraryLink C API&amp;#039;s. &#xD;
&#xD;
##Implementation##&#xD;
&#xD;
Follow [this link][6] to install `LTemplate` package and refer to the document page coming with this package to find the basic example and some type conversion information (well, not like Mathematica you need to specify the type by yourself). In particular we need `mma::IntMatrixRef` as return type and to transfer a 2D array back to Mathematica. Meanwhile, we also need `ra = mma::makeMatrix&amp;lt;mint&amp;gt;` (`ra` stands for raw array) to store the grid information during computation. This `ra` also replaces the double pointer in the original code to handle the array for plot later. Here is the code&#xD;
&#xD;
    #include &amp;lt;LTemplate.h&amp;gt;&#xD;
    #include &amp;lt;numeric&amp;gt;&#xD;
    #include &amp;lt;iomanip&amp;gt;&#xD;
    &#xD;
    &#xD;
    class sandpile {&#xD;
    public:&#xD;
    &#xD;
    	const int dx[4] = { 1,0,-1,0 };&#xD;
    	const int dy[4] = { 0,1,0,-1 };&#xD;
        const int N_size = 781; &#xD;
        const int N_size2 = 390;&#xD;
        &#xD;
    	struct L_coord&#xD;
    	{&#xD;
    		unsigned int x;&#xD;
    		unsigned int y;&#xD;
    	};&#xD;
    &#xD;
    &#xD;
        mma::IntMatrixRef CreateSandpile(int n ) {&#xD;
&#xD;
            auto ra = mma::makeMatrix&amp;lt;mint&amp;gt;(N_size,N_size);&#xD;
            std::fill(ra.begin(),ra.end(),0);&#xD;
    		bool** V_sites = new bool*[N_size];                    &#xD;
    		bool** Move_ = new bool*[N_size];                      &#xD;
    		unsigned int** Odometer = new unsigned int*[N_size];&#xD;
    &#xD;
    		for (int k = 0; k &amp;lt; N_size; k++)&#xD;
    		{&#xD;
    			V_sites[k] = new bool[N_size];&#xD;
    			Odometer[k] = new unsigned int[N_size];&#xD;
    			Move_[k] = new bool[N_size];&#xD;
    &#xD;
    			for (int i = 0; i&amp;lt;N_size; i++)&#xD;
    			{&#xD;
    				Move_[k][i] = false; V_sites[k][i] = false;&#xD;
    			}&#xD;
    		}&#xD;
    &#xD;
    		L_coord* walking_ = new L_coord[N_size*N_size];     		&#xD;
    		V_sites[N_size2][N_size2] = true;&#xD;
    		Move_[N_size2][N_size2] = true;&#xD;
    		ra(N_size2,N_size2) = n;&#xD;
    		walking_[0].x = N_size2;&#xD;
    		walking_[0].y = N_size2;  &#xD;
    		unsigned int x = 0, y = 0;&#xD;
    		int top_ = 0;&#xD;
    		unsigned int lx = 0, ly = 0;&#xD;
    		unsigned int d = 0; &#xD;
    		unsigned int max_of_top = 0;&#xD;
    		unsigned long N_of_Moves = 0;&#xD;
        &#xD;
    		while (top_ &amp;gt;= 0)&#xD;
    		{&#xD;
    			N_of_Moves += 1;&#xD;
    			if (max_of_top &amp;lt; top_) { max_of_top = top_; }&#xD;
&#xD;
    			x = walking_[top_].x;  y = walking_[top_].y;&#xD;
    			&#xD;
    			top_--; Move_[x][y] = false;&#xD;
    			&#xD;
    			d = (ra(x,y) &amp;gt;&amp;gt; 2);&#xD;
    			ra(x,y) = ra(x,y) - (d &amp;lt;&amp;lt; 2);&#xD;
    &#xD;
    			for (int k = 0; k &amp;lt; 4; k++)&#xD;
    			{&#xD;
    				lx = x + dx[k];&#xD;
    				ly = y + dy[k];&#xD;
    &#xD;
    				V_sites[lx][ly] = true;&#xD;
    				ra(lx,ly) += d;&#xD;
    				if (Move_[lx][ly] == false &amp;amp;&amp;amp; ra(lx,ly) &amp;gt;= 4)&#xD;
    				{&#xD;
    					walking_[++top_].x = lx; &#xD;
    					walking_[top_].y = ly; &#xD;
    					Move_[lx][ly] = true;&#xD;
    				}&#xD;
    			}&#xD;
    		}&#xD;
&#xD;
            for (int k = 0; k&amp;lt;N_size; k++)&#xD;
    		{&#xD;
    			delete[] V_sites[k]; delete[] Odometer[k]; delete[] Move_[k];&#xD;
    		}&#xD;
    		delete[] V_sites; delete[] Odometer; delete[] Move_; delete[] walking_;&#xD;
                return ra;&#xD;
        }&#xD;
    };&#xD;
&#xD;
I keep most part intact, only made several essential modification according to the document of LTemplate:&#xD;
&#xD;
 - Include `LTemplate` head file&#xD;
 - Create a class called `sandpile` which wraps around the `CreateSandpile` function to be imported&#xD;
 - Return `mma::IntMatrixRef` object instead of `Clock` object used to print computation time cost&#xD;
&#xD;
##Compile and Load##&#xD;
&#xD;
In a Mathematica notebook, I run the following lines. First I need to load the package&#xD;
&#xD;
    &amp;lt;&amp;lt; LTemplate`&#xD;
    SetDirectory[NotebookDirectory[]] (*put sandpile.h in the same directory as the working nb*)&#xD;
&#xD;
we need to tell Mathematica which class to load and to pick the right member function at the same time&#xD;
&#xD;
    template =LClass[&amp;#034;sandpile&amp;#034;,{&#xD;
        LFun[&amp;#034;CreateSandpile&amp;#034;, {Integer}, {Integer, 2}]&#xD;
        }];&#xD;
&#xD;
If our compiler is set up correctly, with verbose log, we should compile the class to dll just like in VS developer command or xcode or some clang/gcc environment on Linux.&#xD;
&#xD;
    CompileTemplate[template,&#xD;
    &amp;#034;ShellCommandFunction&amp;#034; -&amp;gt; Print, &amp;#034;ShellOutputFunction&amp;#034;-&amp;gt;Print&#xD;
    ]&#xD;
&#xD;
![output][7]&#xD;
&#xD;
The last line is the dll in the `$UserBaseDirectory`. Then we can load the dll with &#xD;
&#xD;
    LoadTemplate[template]&#xD;
&#xD;
Import the class &#xD;
&#xD;
    sp = Make[&amp;#034;sandpile&amp;#034;]&#xD;
&#xD;
and call the member function: &#xD;
&#xD;
    sp@&amp;#034;CreateSandpile&amp;#034;[100]&#xD;
&#xD;
I omitted one ArrayTrim function in C++ code to simplify the process. We actually need it to trim margins with all zeros in a row or column. I choose to implement it quickly in Mathematica with much shorter lines than the c++ version, even though we might transferred many null points back to kernel wasted. Nevertheless, &#xD;
&#xD;
    cleanRow[arr_] := DeleteCases[arr, _?(Total@# == 0 &amp;amp;)]&#xD;
&#xD;
For small set, the &#xD;
&#xD;
    With[{arr = cleanRow@Transpose@cleanRow@(sp@&amp;#034;CreateSandpile&amp;#034;[5000])}, &#xD;
     ArrayPlot[arr, ColorRules -&amp;gt; {0 -&amp;gt; Black, 1 -&amp;gt; Magenta, 2 -&amp;gt; Red, 3 -&amp;gt; Blue}]]&#xD;
&#xD;
![demo2][8]&#xD;
&#xD;
Growing complexity&#xD;
&#xD;
    Style[Grid[Partition[Map[With[{arr=cleanRow@Transpose@cleanRow@(sp@&amp;#034;CreateSandpile&amp;#034;[#])},&#xD;
    ArrayPlot[arr,ColorRules-&amp;gt;{0-&amp;gt;Black,1-&amp;gt;Magenta,2-&amp;gt; Red,3-&amp;gt; Blue}]]&amp;amp;,&#xD;
    {10,20,50,80,100,200,500,800,1000,5000,10000,50000,100000,200000,500000}],5]],&#xD;
    ImageSizeMultipliers-&amp;gt;0.4]&#xD;
&#xD;
![gc][9]&#xD;
&#xD;
&#xD;
I tested the code on 10 million initial points and no problem at all to display it nicely with `ArrayPlot`. The animation at the beginning is only shows a quarter of the whole graph due to symmetry. The color scheme is the same as the [original post][10].&#xD;
&#xD;
 - 1 Million particles at center at t-zero&#xD;
&#xD;
        With[{arr = cleanRow@Transpose@cleanRow@(sp2@&amp;#034;CreateSandpile&amp;#034;[1000000])}, &#xD;
        ArrayPlot[arr,ColorRules -&amp;gt; {0 -&amp;gt; Black, 1 -&amp;gt; Magenta, 2 -&amp;gt; Red, 3 -&amp;gt; Blue}]]&#xD;
&#xD;
![demo3][11]&#xD;
&#xD;
 - 10 Million particles at center at t-zero (only show quarter) and the result is attached in csv format.&#xD;
&#xD;
        ImageCrop@&#xD;
         Colorize[sp1@&amp;#034;CreateSandpile&amp;#034;[10000000], &#xD;
          ColorRules -&amp;gt; {0 -&amp;gt; White, 1 -&amp;gt; Green, 2 -&amp;gt; Purple, &#xD;
            3 -&amp;gt; RGBColor[&amp;#034;#D4AF37&amp;#034;]}]&#xD;
&#xD;
![demo4][12]&#xD;
&#xD;
##Summary##&#xD;
&#xD;
 - Use  `LibraryLink` based package `LTemplate` to call a C++ function with one integer input and 2D integer output.&#xD;
 - Demonstrate how to pass 2D array in C++ back to Mathematica&#xD;
 - Use `ArrayPlot` to visualize tensor computed in C++ environment&#xD;
 - Safely wrap `Manipulate` or `ListAnimate` around external library function&#xD;
 - Mathematica implementation can also be found [here][13]&#xD;
 - [Analytic research][14] on this topic&amp;#039;s complexity&#xD;
&#xD;
&#xD;
  [1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=demo.GIF&amp;amp;userId=23928&#xD;
  [2]: https://www.wolframscience.com/nks/notes-7-9--self-organized-criticality/&#xD;
  [3]: https://www.youtube.com/watch?v=1MtEUErz7Gg&#xD;
  [4]: https://community.wolfram.com//c/portal/getImageAttachment?filename=7183note.jpg&amp;amp;userId=23928&#xD;
  [5]: https://github.com/hayk314/Sandpiles/blob/master/C++/AbelSand/AbelSand/Abel.cpp&#xD;
  [6]: https://github.com/szhorvat/LTemplate&#xD;
  [7]: https://community.wolfram.com//c/portal/getImageAttachment?filename=2285output.jpg&amp;amp;userId=23928&#xD;
  [8]: https://community.wolfram.com//c/portal/getImageAttachment?filename=5719demo2.jpg&amp;amp;userId=23928&#xD;
  [9]: https://community.wolfram.com//c/portal/getImageAttachment?filename=3273demo4.jpg&amp;amp;userId=23928&#xD;
  [10]: https://github.com/hayk314/Sandpiles/blob/master/C%2B%2B/AbelSand/Debug/Abel1000000.png&#xD;
  [11]: https://community.wolfram.com//c/portal/getImageAttachment?filename=3492demo3.jpg&amp;amp;userId=23928&#xD;
  [12]: https://community.wolfram.com//c/portal/getImageAttachment?filename=nb.png&amp;amp;userId=23928&#xD;
  [13]: https://www.complex-systems.com/abstracts/v17_i01_a02/&#xD;
  [14]: https://www.complex-systems.com/abstracts/v17_i01_a02/</description>
    <dc:creator>Shenghui Yang</dc:creator>
    <dc:date>2020-04-07T04:51:16Z</dc:date>
  </item>
</rdf:RDF>

