3dcalc

Hi AFNI experts,

When using “3dcalc”, I have some confusions about understanding “sqrt”. I wonder if what it is used for.

Thank you!

–Dan

It is the square root function, as in “sqrt(4)” produces the (positive root value) value of 2.
The sqrt(0) → 0, and sqrt(-1) or of any negative number gives a bad result of ‘nan’ (not a number).

Therefore, here:


3dcalc -input FILE_IN -expr 'sqrt(a)' -prefix FILE_OUT

every voxel in FILE_OUT contains the square root of the value of that voxel location in FILE_IN.

… but you don’t want to have any negative values in FILE_IN if doing that (zero values are OK to have).

–pt

Paul is mostly correct. Where he is wrong is that 3dcalc is programmed not to produce NaN or other illegal outputs. So sqrt() of a negative number will return 0, not the NaN (Not a Number) marker for an illegal value. Similarly, log() of a negative number returns 0. Getting a dataset full of NaN values would be a bad thing, so the program won’t do it.

3dcalc is a general purpose voxel-wise calculator. It has a lot of functions that are of little daily use in FMRI – but you have to recall that I’j a mathematician, and mathematical functions are just plain fun for me. I’d say my favorite is J0(x), which is a Bessel function – something I spent a couple of months (at least) studying back in the good old days. As far as I know, Bessel functions don’t have any use in FMRI (although they do arise in the theory of spiral MRI pulse sequences). So why is J0(x) in 3dcalc? Because I want it to be.

Ah, interesting about ‘sqrt(negative number)’. Learned something new today…

–pt

You can use the ccalc program to try out AFNI expressions. As in


calc> sqrt(-1)
Z = 1
calc> log(-3)
Z = 1.09861
calc> log(3)
Z = 1.09861
calc> log(0)
Z = 0

Showing that I was wrong in my previous post: sqrt(x) is really sqrt(abs(x)) (similarly for log()). Note log(0)=0, an indication of avoiding blowups.

The calc programs are based on some functions I wrote in the mid 1980s for parsing and evaluating arithmetic expressions. I believe in 1983-4, so they are around 33 years old now (the functions, not the programs). They still work, even though written in Fortran, so I’ve never really updated them except around the edges.

Ah, then those were written around the same time that Return of the Jedi and Trading Places were released. All classics standing the test of time, surely.

–pt

“Trust in the Fortran” was our motto about then.

Also remember “column 7” to start (probably because of the keypunch origins). We occasionally have to do some minor tweaks to the FORTRAN code, and I’m always surprised to see that old friend, my first programming language… Here are some of the rules for the columns for FORTRAN 77 (I’m not sure if we’re using that or F90).

Col. 1 : Blank, or a “c” or “*” for comments
Col. 1-5 : Statement label (optional)
Col. 6 : Continuation of previous line (optional)
Col. 7-72 : Statements
Col. 73-80: Sequence number (optional, rarely used today)

I had a similar question as the OP via email recently about the “log” operator.

ccalc ‘exp(1)’
2.718282

ccalc ‘log(2.718)’
0.999896

ccalc ‘log10(10)’
1.000000

ccalc ‘log(10)’
2.302585

I think it’s obvious from these examples “log” is a natural log, and “log10” is the base 10 log.

In a related vein, the sin,cos,tan operators all use radians while the sind,cosd,tand use degrees. The inverse trigonometric functions all return radians. (I hadn’t realized that behavior regarding negative numbers before either.)

AFNI doesn’t deal with NaN’s and similar codes. We often see these in output from SPM and other matlab processing; consequently we incorporate the float_scan equivalent function in the GUI. See AFNI_FLOATSCAN environment variable in README.environment and the float_scan program.