Arithmetics

There are two types of arithmetic expressions, a vector type which creates SCANs, and a scalar type which produces floating point numbers. The calculate (sect. 15.3.4) and vcalculate (sect. 15.3.81) commands invoke the interpreter of vector expressions. Whereas the scalar interpreter evaluates parameters and qualifiers.

Both interpreters analyze arithmetic commands in terms of

expressions
Add ($+$), subtract ($-$) and compare (<, >)
terms
Multiply ($*$), divide ($/$), AND (&), OR ($\mid$) and XOR ($\wedge$)
factors
Which consist of numbers, function or expressions.

The precedence of the multiplication, division, bit manipulation and function calls is higher than the precedence of addition and subtraction. The interpreter knows, how to deal with parentheses. The functions are described beginning in section 14.

These are examples of a scalar and a vector expression:

SPECTRA> $*$ = (2 + 3$*$4)$*$sqrt( exp10(2)/5 + 5)/(2 + 8)
SPECTRA> calc spec3 = log( spec2/spec1)

All operators consist of one character only, e.g. there is no power-of operator ($**$). But there is a function (power()) that does the job. There is also no $==$ operator, an example for testing the equality is given below.

The operators ${\tt <}$ and ${\tt >}$ have different meanings in scalar and in vector expressions. In scalar expressions $a > b$ has the value 1, if $a$ is greater than $b$. Otherwise the expression has the value 0. The same applies for <. In a vector expression > and < select points, which have y-values above or below a certain limit. Example:

SPECTRA> calc new_name = old_scan > 0
After this command new_name contains those points of old_scan, which have positive y-values.

The operator ! returns 1, if the following expression is 0. Otherwise it returns 0, e.g.:

...
inquire scan_id " Enter SCAN to be processed "
if !search_scan( scan_id) 
  say " The scan "scan_id" does not exist"
  end 
endif 
...
In this example the user is asked to enter a SCAN id. The program checks whether the SCAN exists. If not, an error message is generated and the execution of the command file is stopped. The parameter of the SAY command is an example for symbol concatenation.

The not-operator can also be used to test the equality of numbers, e.g.:

...
if !(x - 3)  
  say " X equals three"
  ...
endif 
...

The operators &, $\mid$ and $\wedge$ compare two expressions bit by bit. The $\wedge$ is an exclusive OR, e.g.:

SPECTRA> $*$ = 6 & 5
4
SPECTRA> $*$ = 6 $\mid$ 5
7
SPECTRA> $*$ = 6 $\wedge$ 5
3

Lets look at the interpreter of vector expressions in some detail, e.g.:

SPECTRA> read bpu1
SPECTRA> calc bpu1 = bpu1/integral(bpu1)
In this example, the y-values of bpu1 are divided by the integral of the spectrum. Bpu1 is replaced by the result. One could also create a new SCAN for the result:
SPECTRA> calc new_name = bpu1/integral(bpu1)
or
SPECTRA> y(3) = bpu1/integral(bpu1)
The last command line creates a SCAN named scan_3.

What happens if one mixes two spectra with different x-values? Consider this example:

SPECTRA> calc test = log(spec1/spec2)
The x-values of test are copied from spec1, because SPECTRA takes the x-values from the first SCAN on the right side of the "=". If the ranges of the x-values do not match, test contains only those points which are in the intersection of all input SCANs.

Before the calculation is done, the y-values of spec2 -- and possibly others - are linearly interpolated at the x-values of spec1. The verb vcalculate (sect. 15.3.81) does no interpolation. It treats the x- and y-columns as vectors, requiring only that they have the identical length.

If you mix x- and y-values in one expression, like

SPECTRA> calc test = log(spec1/spec2)$*$x(spec1)
it does not matter, whether you enter x(spec1) or x(spec2). SPECTRA takes the x-values of spec1 anyway.

Changing the x-values of a SCAN is also possible:

SPECTRA> calc x(spec1) = x(spec1)$*$5 + 1000
Don't try to mix x-values from different spectra with calc.



Subsections