Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have written a Mathematica script that is to be run periodically on a Raspberry Pi. The code takes about 3 seconds to execute if I test it in a CLI Mathematica session. However, when I execute the script with

wolfram -script script.w > out.csv

it takes more than 10 seconds. The output of the script is a single String three ASCII characters long, so writing output to file does not take a significat part of the time. I thus assume most of the extra time comes from kernel initialization.

I'd like to initialize Mathematica kernel once and then run my script periodically without needing to initialize the kernel every time. Is this possible?


UPDATE

Following the answer from this related question I tried to make it work like this:

mkfifo mmpipe
tail -f mmpipe | wolfram -noprompt &

However, when I pipe a command that contains a file-importing function like ReadList, it stays in interactive mode and does not exit to shell:

echo 'ReadList["/home/pi2/data.csv","String"]'>mmpipe
{ ... , "2014/02/05 21:35:02,0.28", "2014/02/05 21:40:02,0.00", "2014/02/05 21:50:02,0.00"}
_

So I can't use it in an automated process.

share|improve this question
    
Probably you could keep the kernel running and send the scripts using MathLink. –  rhermans Feb 5 at 15:44
1  
You could use the scheduled tasks functionality of Mathematica, and set up a task to be run every 30 minutes. I.e. don't schedule this using an external tool. Schedule it within Mathematica. Does this help? –  Szabolcs Feb 5 at 16:17
    
Is .w the recommended extension for packages/scripts now? :-/ –  Szabolcs Feb 5 at 16:17
1  
Found a closely related question: mathematica.stackexchange.com/questions/23217/… –  shrx Feb 5 at 19:57
1  
@shrx MathLink is a communication protocol used by Mathematica and a corresponding API (has ready-made bindings for C/C++/Java/.NET). The kernel and the front end communicate through MathLink. The main kernel and subkernels used in parallel calculations also communicate through MathLink. You could theoretically write alternative front ends using MathLink. Some people have: there's something Emacs-based and two shell-based ones: jmath and mash. I never tried these. But if you were to ... –  Szabolcs Feb 6 at 21:07

1 Answer 1

Alright, I managed to make a clunky working script with the help from @Szabolcs' answer here and some testing of the fifo procedure:

#!/bin/bash

pipe=/home/pi2/mmpipe

# check if pipe exists; if not, create it
if [[ ! -p $pipe ]]; then
        mkfifo $pipe
fi

# check if kernel is running; if not, start it and define functions
if [ $(ps aux | grep WolframKernel | grep -v grep | wc -l) -eq 0 ]; then
    	tail -f $pipe | wolfram -noprompt &
    sleep 6 # this is needed; functions need to wait for the kernel to initialize
    echo 'function1[]:=...'>$pipe
    	sleep 1 # this is also needed; kernel needs some time with each new definition
    	echo 'function2[]:=...'>$pipe
fi

echo 'run main mathematica code here;'>$pipe

This solution works only if Mathematica code does not output anything. Every line needs to end with ; and Print[] should not be used. Otherwise the script stays in interactive mode and does not exit to shell. Mathematica output can be saved with Export[], though.


UPDATE

I'm having some trouble with this solution. After some time of working without problems, the second defined function (I have only two) is no longer evaluated. Running echo '?function2'>$pipe returns only "Global`function2" like its definition was somehow unset. I have managed to incorporate the second function in the main code and leave it out from the initial definitions, but this method proves to be really unreliable.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.