What's new in Agena 3.14.0
Apr 24, 2024
- The assignment feature in `if` and `while` clauses has been extended: You can now use the percentage sign as a placeholder for the variable name in the condition, for example:
- > i := 0.1;
- > while logn := ln(i), % < -0.9 do
- > print(i, logn);
- > i +:= 0.1
- > od;
- 0.1 -2.302585092994
- 0.2 -1.6094379124341
- 0.3 -1.2039728043259
- 0.4 -0.91629073187416
- When using the percentage notation with `while` loops, the assignment statement in the `while` clause is always redone when control flow is returning to the start of the `while` loop, before checking whether to execute the loop body once again.
- This is contrary to the existing logic where the assignment is done only once, so the following will loop forever since `logn` is not updated in the loop body
- > i := 0.1;
- > while logn := ln(i), logn < -0.9 do
- > print(i, logn);
- > i +:= 0.1
- > od;
- The percentage sign cannot be used in the body or succeeding statements as it usually represents the modulus operator.
- This release has been named after the city of Scottsboro, Jackson County, Alabama. It has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.13.5 (Apr 23, 2024)
- On some platforms, `csc` could crash in the complex domain. This has been fixed.
- Tweaked `frexp10`, `zx.ASN` and `zx.ACS` a little bit.
- `zx.SQR` ignored its second argument. This has been fixed.
- New `zx.MOD` computes the modulus and new `zx.HYP` the hypotenuse of two numbers in approximate ZX Spectrum machine precision. New `zx.SIG` returns -1 with negative arguments and +1 otherwise. New `zx.ERFC` implements the complementary error function.
New in Agena 3.13.4 (Apr 21, 2024)
- `csc`, `sec` and `cot` returned `undefined` in the epsilon neighbourhood of the poles. This has been fixed. The functions now return finite values except for the poles themselves. `csc` and `sec` have also become 15 percent faster.
- The accuracy of `cot` with large negative and positive real arguments has been significantly improved by a factor of 3.
- On some platforms, `cot` and `coth` could crash in the complex domain. This has been fixed.
- `arcsech` has been tweaked in the complex domain.
- New `stack.cotd`, `stack.cscd` and `stack.secd` compute the cotangent, cosecant and secant of the top element of the current numeric stack, and new `stack.erfd` computes the error function.
New in Agena 3.13.3 (Apr 18, 2024)
- Besides a sequence, `ops` now accepts a table or register with index positions. Example:
- > f := << () -> 10, 20, 30, 40 >>
- > ops([2, 4], f()):
- 20 40
- `member` can now search sets and does not return an index in case of success, but just `true` and `null` otherwise.
- `augment` has become ten to 20 percent faster with two to five arguments.
- Corrected error messages of `reverse`.
- `implies` now returns an error if given no numbers or booleans.
- Cleansed the code to prevent compiler warnings on OS/2 and Mac OS X.
- Extended the regression test cases.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.13.2 (Apr 15, 2024)
- Added the new `cuckoo` package which implements a Cuckoo filter for string dictionaries, an alternative to a Bloom filter. Both are space-efficient data structures designed to answer approximate membership queries:
- Is a string _definitely not_ part of a dictionary ?
- Is a string _likely_ to be part of a dictionary ?
- Contrary to the bloom package, `cuckoo` allows to delete entries from the filter and is 10 % faster when creating new filters and 15 % faster when querying them. Example:
- > import cuckoo;
- > c := cuckoo.new(13500); # max. of 13,500 hash entries
- > cuckoo.include(c, 'abc'); # insert an entry
- > cuckoo.find(c, 'abc'): # find an entry
- true
- > cuckoo.remove(c, 'abc'); # remove the entry
- > cuckoo.find(c, 'abc'): # find the entry removed
- false
- The package is based on the C `libcuckoofilter` library created by Jonah H. Harris and published on Github.
- `bloom.include` and `bloom.find` now accept a string instead of a hash value for the second argument. If given a string, the functions internally compute its MurmurHash3 hash value and then proceed as already implemented. In this mode, the functions are around 15 percent faster than before.
- New `skycrane.obcount` takes a table, sequence or register and counts the number of occurrences of each of its values.
- Example:
- > import skycrane
- 1 is included 4 times, 2 is included twice, 3 only once, etc.:
- > skycrane.obcount([1, 1, 1, 2, 2, 1, 3, 8, 9, 8, 9]):
- [1 ~ 4, 2 ~ 2, 3 ~ 1, 8 ~ 2, 9 ~ 2]
- Some underlying administrative data structure, sorting and hashing functions have been tweaked a little bit by forced inlining. Also tuned auxiliary 64-bit trigonometric, logarithmic and error functions this way plus ZX Spectrum math and 80-bit floating point functions.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.13.0 (Apr 2, 2024)
- Introduced the C-style conditional `for` loop. It initialises a new local control variable, checks a `while` or `until` condition and then executes the loop body. When the loop exits, the last value of the loop control variable is available in the block that is surrounding the loop.
- Note that you explicitly have to change the loop control variable in the loop block or you might go into an infinite loop otherwise. Also note if you change the loop control variable by a fractional value, the `while` or `until` condition might never be met due to accumulating round-off errors.
- The `redo` and `relaunch` statements are not accepted within the loop body, while `skip` and `break` are.
- `calc.sections` has been precautiously hardened against stack corruption.
- This release has been named after the place of Cade in St. Martin Parish, Louisiana, and has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
- From now on, due to lack of public interest there will no longer be Raspberry Pi, Solaris, Red Hat and rase distributions available in the Sourceforge Download section. If you need one, request it via the Agena Sourceforge Forum, please.
New in Agena 3.12.1 (Apr 2, 2024)
- The new function `calc.fmaxbr` estimates the maximum location of a univariate or multivariate function over a given range, combining Golden section search with parabolic interpolation. Example:
- > calc.fmaxbr(<< x -> -x^2 >>, -0.1, 0.1):
- New `calc.fmaxgs` is similar to `calc.fmaxbr` but using Golden section search only.
- `calc.maximum` has become 40 percent faster.
- `calc.maximum` and `calc.minimum` now check whether their results really exist by checking whether the input function is defined at the calculated points.
- `calc.arclen` and `calc.sinuosity` now accept multivariate functions. See the Primer and Reference on how to pass the second, third, etc. argument in the respective calls.
- With univariate functions, as before, you do not have to change the code if - but only if - you have not been passing optional arguments as the defaults did not change. Example:
- > calc.arclen(<< x, a -> sin(x + a) >>, 0, 1, 1, eps=1e-5):
- 1.0402463016211 4.1593273947496e-005
- Added further calculus cases to the testsuite.
New in Agena 3.12.0 (Apr 1, 2024)
- The new function `calc.eps` computes a mathematical epsilon value that takes into account the magnitude of the function value at a given point.
- `calc.fminbr`, `calc.fmings`, `calc.simaptive`, `calc.gtrap`, `calc.sections`, `calc.regulafalsi`, `calc.zeros`, `calc.zeroin`, `calc.variance`, `calc.minimum` and `calc.maximum` now accept multivariate functions. See the Primer and Reference on how to pass the second, third, etc. arguments in the respective calls.
- With univariate functions, as before, you do not have to change the code if - but only if - you have not been passing optional arguments as the defaults did not change.
- If you want to pass options, you now have to give them in the explicit `optionname = value` notation. Example:
- > calc.regulafalsi(<< x, a -> sin(x + a) >>, 0, 2, Pi/2, eps = DoubleEps): # root of cosine, actually, due to a = Pi/2 shift.
- 1.5707963267949
- The `checkrange` option to `calc.regulafalsi` has been removed. Now, the root is always being checked whether it is in the interval of interest. This was the default behaviour before, anyway.
- `calc.variance` can no longer optionally return absolute values. All results will be given per unit on the abscissa, which was the default mode before. Multiply the return by `round(left border) - round(round border)` to get an absolute value.
- `calc.gauleg`, `calc.intcc`, `calc.intde`, `calc.intdei` and `calc.intdeo` now require options to be explicitely given in `optionname = value` notation. See the Primer and Reference on how to pass the second, third, etc. arguments in the respective calls. If you have been passing options to these functions, you have to change the code.
- Example:
- > calc.intdeo(<< x, a -> sin(x)/(x + a) >>, 1, 0, omega = 1, eps = Eps):
- 0.62471325639277 8.3556975456747e-008
- Improved error messages of `calc.diff`, `calc.xpdiff`, `calc.limit`, `calc.iscont` and `calc.eulerdiff`.
- `calc.arclen` has been tuned the function by 33 percent.
- `calc.differ` has become 25 percent faster. There are also no longer exceptions with multivariate functions.
- `calc.sections` often returned empty sequences indicating no roots, causing problems with `calc.zeros`, as well. This has been fixed.
- `calc.zeroin` often did not return roots, also adversely affecting `calc.zeros`. This has been fixed.
- `checkoptions` incorrectly validated the `posint`, `negint` and `nonnegint` pseudo-types. This has been fixed.
- Extended the calculus test cases.
- This release has been named after the town of Berwick in St. Mary Parish, Louisiana, and has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.11.5 (Mar 25, 2024)
- Tuned, extended and fixed calculus functions that compute integrals:
- `calc.intdei` and `calc.intdeo` now remember the last epsilon setting given by the user and run 40 % faster with succeeding calls done with the same epsilon value. This also benefits the wrapper function `calc.integ` (see below).
- `calc.gauleg`, `calc.intde`, calc.intdei`, `calc.intdeo` and `calc.intcc` now accept multivariate functions. See the Primer and Reference on how to pass the second, third, etc. arguments in the respective calls. With univariate functions, as before, you do not have to change the code.
- `calc.integ` has been rewritten to support multivariate functions. Optional epsilon, omega and sample values must now be given as explicit options, so you may have to adapt your code. Example:
- > calc.integ(<< x, a -> x + a >>, 1, 2, 0, eps=hEps, omega=1, samples=100):
- 1.5 2.999999997239e-015
- If the third argument to `calc.intdeo` was zero, the interpreter could crash on some platforms. This has been fixed.
- If the number of sample points is zero, `calc.gauleg` now automatically sets it to 20 points internally. This prevents segmentation faults on some platforms and also false results of exactly zero.
- If you pass zero as an epsilon value to `calc.intde`, calc.intdei`, `calc.intdeo` and `calc.intcc`, then it is automatically reset to the default setting 1e-15 to avert any infinite loops.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.11.4 (Mar 22, 2024)
- The `addup` and `mulup` operators can now intuitively approximate series and products and are easier to use and consume much less memory than the `foreach` operator or the other flavours of `addup` and `mulup`. Just pass the function representing the series or product plus the start and stop value and optionally a step size. Multivariate functions are supported. `addup` uses Kahan-Babuska summation on all platforms to keep round-off errors as small as possible and `mulup` internally uses 80-bit precision on Intel/AMD platforms to do the same.
- Example 1: Compute the sum
- ) ---- ~ ln(2)
- / k
- 2 k
- k = 1
- > addup(<< k -> recip(2**k*k) >>, 1, 50):
- 0.69314718055995
- Example 2: Compute the product
- '
- ' | | / 1 51
- | | |1 - ----| = --- ~ 0.5
- | | | 2 | 100
- | | k /
- k = 2
- > mulup(<< k -> (1 - recip square k) >>, 2, 50):
- 0.51
- The operators approximate series and products more than twice as fast as numeric for loops combined with `math.kbadd` for Kahan-Babuska summation (series) and `long` 80-bit precision package functions (products) to minimise round-off errors.
- `calc.fprod` now accepts multivariate functions.
- With fractional step sizes, the `foreach` operator could go into an infinite loop if function calls did not result into numbers. This has been fixed.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.11.3 (Mar 16, 2024)
- `units.cm` did not correctly convert Russian handspans. This has been fixed. Plus, the function now accepts the following options:
- 'piad', the argument is taken to be in Russian handspans (piads) with 1 piad = 17.8 cm.
- 'span', the argument is taken to be in US spans with 1 span = 22.86005 cm.
- 'hand', the argument is taken to be in US hands with 1 hand = 4 inches = 10.16002 cm.
- 'link', the argument is taken to be in US links with 1 link = 2/3 feet = 20.11684 cm.
- Also changed conversion factor from 1 inch = 2.54 cm to 1 inch = 2.54000508 cm. Example:
- > units.cm(1, 'piad'):
- 17.8
- `units.inch` now accepts the following options:
- 'piad', the argument is taken to be in Russian handspans (piads) with 1 piad = 7.01 inches.
- 'span', the argument is taken to be in US spans with 1 span = 9 inches.
- 'hand', the argument is taken to be in US hands with 1 hand = 4 inches.
- 'link', the argument is taken to be in US links with 1 link = 7.92 inches.
- Also changed default conversion factor from 1 inch = 2.54 cm to 1 inch = 2.54000508 cm. Example:
- > units.inch(2, 'span'):
- Changed conversion factors in `units.km` and `units.mile` from 1 standard mile = 1.609344 km to 1 std. mile = 1.6093440006 km and from 1 nautical mile = 1.852 km to 1 nmi = 1.852216 km.
New in Agena 3.11.1 (Mar 6, 2024)
- New `math.cscd` and `math.secd` take an argument in degrees and compute the cosecant and secant, respectively
- Introduced the new `units` package which converts between physical units. It is some sort of a quick-and-dirty solution in the sense that it spares you a lot of typing and getting results as fast as possible
- units.celsius` takes a value in Fahrenheit and converts it to degrees Celsius
- units.fahren` takes a value in Celsius and converts it to degrees Fahrenheit
- units.mile` takes a value in kilometres and converts it to statute miles. Nautical miles are supported by passing any second argument
- units.km` takes a value in statute miles and converts it to kilometres. Nautical miles for the input are supported by passing any second argument
- units.foot` takes a value in metres and converts it to International feet. US, UK, Indian and historical Rhineland feet are supported by providing the option 'US', 'UK', 'India' or 'Rhineland', respectively. Likewise, new `utils.meter` takes a value in feet and converts it to metres, with the beforementioned options supported, as well
- units.yard` converts from metres to yards
- By passing the new fifth argument `false` to `calc.regulafalsi`, you can switch off the check on whether the computed result is within the given borders. In this case the function does not return `null` but the iterated value. The function now in general also automatically stops computation if it took more than 250 iterations, so it cannot go into an infinite loop any longer
- math.epsilon` returned exactly zero with methods 0 and 1 when its argument was zero. This has been fixed, and now `ulp` will be returned, see the Primer and Reference for details. Thus, `calc.differ` no longer issues an error when differentiating a function at the origin
New in Agena 3.11.0 (Mar 4, 2024)
- New `linalg.eigen` returns both the eigenvectors and the eigenvalues of a symmetric matrix
- New `linalg.islower` checks whether a square matrix is in lower triangular form, that is all the entries above the main diagonal are zero
- New `linalg.isupper` checks whether a square matrix is in upper triangular form, that is all the entries below the main diagonal are zero
- Removed a memory leak from `linalg.eigenval` when internal memory allocation failed
- New `math.sind`, `math.cosd`, `math.cotd` and `math.tand` take an argument in degrees and compute the sine, cosine, cotangent and tangent, respectively, in radians
- math.agm` now accepts complex numbers
- New `math.tocomplex` converts a number x into the complex number x + I*0. When given a complex number, it is simply returned. The function is useful to compare numbers with complex numbers using the relational operators `=` and `<>`
- New `calc.bessel0` and `calc.bessel1` return the modified Bessel function of order zero and one, respectively. Both functions can also exponentially scale their results
- Documented `fractals.esctime` with which you can compute (and draw) escape-time fractals. See file `lib/fractals.agn` for a lot of examples
- The DOS edition now includes the `fractals` package
- The C API function `agn_ccall` has been extended to accept functions that return a number instead of a complex number
- This release has been named after the village of Converse in Sabine Parish, Louisiana, close to Texas and has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks
New in Agena 3.10.7 (Mar 3, 2024)
- New `math.agm` approximates the arithmetic-geometric mean of two real numbers.
- New `calc.elliptic1` computes the complete and incomplete elliptic integral of the first kind.
- New `calc.elliptic2` computes the complete and incomplete elliptic integral of the second kind.
- New `calc.jacobian` computes the Jacobian elliptic functions sn, cn and dn.
- The `skipfaulty` option to `io.lines` has been extended to deal with empty lines, that is, if a line read in is of zero length, it will be ignored and the next line will be read immediately. This also works with files ending in an empty line.
- This release has be
New in Agena 3.10.6 (Feb 27, 2024)
- New `linalg.eigenval` computes the eigenvalues of a square matrix.
- New `calc.hyp1f1` computes the confluent hypergeometric function 1F1 aka Kummer's function of the first kind.
- New `calc.hyp2f1` computes the Gaussian or ordinary hypergeometric function 2F1
- On Intel/AMD platforms, the accuracy of `calc.cheby` deteriorated in Agena 3.10.5. This has been fixed.
New in Agena 3.10.5 (Feb 22, 2024)
- The new `!!` operator takes a magnitude and an argument and creates a complex number in Cartesian form. It is equal to the `cartesian` function but 25 percent faster.
- The new functions `os.isarm32` and `os.isarm64` check whether Agena is running on Raspberry Pi OS 32-bit or 64-bit.
- Reduced memory consumption of `calc.cheby` and `calc.chebycoeffs` on all supported platforms by one kByte.
- The accuracy of `calc.cheby` on 32-bit and 64-bit Raspberry Pi has been slightly improved. You may also change its fourth argument, the order of the interpolant, to another value to get better accuracy. Remember that on ARM CPUs, the function can only calculate with 64-bit presision, and not 80-bit.
- Source file `agnhlps.c` did not compile on Raspberry Pi 64-bit. This has been fixed.
- The Primer and Reference and the Quick Reference have been improved.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.10.4 (Feb 12, 2024)
- Added the following new options to `io.lines`:
- `skipfaulty`: when set to `true`, all lines with incorrect field numbers are skipped and the function will not return `fail`; default is: `false`.
- `header`: when given, the very first line in a file will be skipped, default is `false`.
- `ignore`: applies a function on every line and if it evaluates to `true`, the line will be skipped.
- `utils.readcsv`: besides accepting the existing `skipemptylines` option, the shorter name `skipempty` will now be accepted, as well.
New in Agena 3.10.2 (Feb 4, 2024)
- With structures containing numbers only, both `sort` and `sorted` have become at least four times faster when being called with the new 'number' option, by using Introsort or Heapsort, depending on the size. Note that when given, you cannot provide a sorting function as this mode supports sorting in ascending order only.
- As a by-product, `stats.freqd`, `skycrane.sorted` and `avl.indices` have become faster, as well.
- With the new `bailout=false` option, `strings.fields` no longer issues an error if a given field has not been found in the input string. Instead, the function in this case will return an empty sequence giving the programmer more flexibility to handle exceptions. By default, the function still issues an error if a field does not exist, so you do not have to change your code.
- Strings can now be printed in single quotes at the console by passing the new -q command-line switch or by setting
- > environ.kernel(enclose=true)
- in the Agena session.
- Likewise, the new -Q and -b command-line switches set strings in double quotes or in backquotes, respectively, which is equal to setting
- > environ.kernel(enclosedouble=true)
- > environ.kernel(encloseback=true)
- The new function `tables.isall` checks whether all elements in a table are of a given type. Eligible types that the function accepts are 'number', 'integer' (numbers that are all integral), 'complex', 'string' and 'boolean'. With tables, sequences and registers, you can also query 'posint' (positive integers), 'positive' (positive numbers), 'nonnegint' (non-negative integers) and 'nonnegative' (non-negative numbers). The function is at least fifteen times faster than checking structures with the `satisfy` function. Examples:
- > tables.isall([1, 2, Pi], 'number'):
- true
- which is equal to:
- > tables.isall([1, 2, Pi], number):
- true
- > tables.isall([1, 2, 3], 'integer'):
- true
- > tables.isall([1, 2, 3], integer):
- true
- > satisfy(<< x -> x :: integer >>, [1, 2, 3]):
- true
- Likewise, `sequences.isall` is checking sequences, `registers.isall` is checking registers and `sets.isall` is checking sets. Numeric arrays with C doubles are being checked with new `numarray.isall`.
- Tweaked `tables.indices` and `tables.entries` by avoiding internal memory re-allocation. Also revised and cleaned up the underlying `intvec` C library that is used to collect integer indices.
- Removed a memory leak from `strings.fields` in case memory could not be allocated internally.
- In the C API, you can now also pass a positive stack index to `agn_seqsetinumber` and `agn_regsetinumber`.
- The new C API function `agn_setinumber` sets a number to a table array.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.10.1 (Jan 31, 2024)
- New `strings.jaro` computes either the Jaro-Winkler or Jaro similarity of two strings, returning a value between 0 and 1. Example:
- > strings.jaro('similarity', 'similariyt'): # Jaro-Winkler
- 0.98
- > strings.jaro('similarity', 'similariyt', false): # Jaro
- 0.96666666666667
- `strings.dleven` has been extended and computes the Damerau-Levenshtein similarity, a normalised value between 0 and 1, if given `true` as the third argument. Example:
- > strings.dleven('similarity', 'similariyt', true):
- 0.94
- New `strings.ngrams` produces all the n-grams of a string.
- New `strings.obfusxor` obfuscates a string by XORing.
- `strings.strcoll` now accepts a third argument that determines the locale to be used for the comparison of two strings, just for the single call and without permanently changing the locale on the system. Examples:
- > strings.strcoll('aäüßou', 'aausou'):
- > strings.strcoll('aäüßou', 'aausou', 'German'):
- On some platforms you may have to pass a combination of the ISO 639-1 language code and the ISO 3166-1 region code instead of the full language name, e.g.:
- > strings.strcoll('aäüßou', 'aausou', 'de_DE'):
- When called with a string, `skycrane.getlocales` now returns the full name of the language and country for a combination of the ISO 639 language code and the ISO 3166 region code. Examples:
- > skycrane.getlocales('he'):
- Hebrew
- > skycrane.getlocales('he_IL'):
- Hebrew (Israel)
- When called with any Boolean, then the function now determines whether the locales included in an internal mapping list (see file lib/skycrane.lib) are supported by the operating system, and returns the supported ones in a table.
- When called the very first time in a session, the function has become 13 times faster, by using internal tables with currently used language and country/region codes.
- Furthermore, when called subseqently again with the same argument, the function takes the result from its internal store, significantly speeding it up.
- New `hashes.superfast` computes the SuperFastHash of a string.
- New `hashes.ispell` computes the ISpell hash of a string.
- `hashes.bkdr` now accepts a fourth argument, the initial hash value which defaults to 0 for downward compatibility.
- For better portability of Lua code to Agena, added the Lua 5.4 functions `tables.concat`, `tables.pack` and `tables.unpack`:
- `tables.concat` is similar to the `join` operator and concatenates all the strings and/or numbers in a table to a string.
- `tables.pack` returns a new table with all arguments stored into keys 1, 2, etc. and with a field "n" with the total number of arguments.
- `tables.unpack` is equal to `unpack`, but for tables only.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.10.0 (Jan 28, 2024)
- Introduced the new `unless` keyword which can be used along with `skip`, `break` and `return`. It does the opposite of the `when` clause:
- `break unless`: The loop will _not_ be left if the condition, evaluated to a boolean, results to `true`:
- > for i to 10 do
- > break unless i < 4;
- > print(i)
- > od
- `skip unless`: The rest of the loop will _not_ be skipped if the condition, evaluated to a boolean, results to `true`:
- > for i to 10 do
- > skip unless i < 4;
- > print(i)
- > od
- `return unless`: The code immediately returns if the given condition evaluates to `false` and can be combined with the `with` clause:
- > a := 0;
- > return unless a <> 0 with true; # bail out if a is zero
- The idea has been taken from Perl.
- New `strings.bigrams` computes the bigrams of a string, either as substrings or encoded signed 4-byte integers.
- > strings.bigrams('abcd'):
- seq(ab, bc, cd)
- > strings.bigrams('abcd', true):
- seq(6357090, 6422627, 6488164)
- New `strings.dice` returns the Dice's coefficient of two strings.
- New `math.hamming` computes the Hamming distance of two integers considered as binary values, that is, as sequences of bits.
- Introduced new functions that count the number of elements in unions, intersections and differences of tables, sequences, registers and sets, without the overhead of creating these structures: They are roughly thrice as fast as first creating and then counting them:
- tables.numunion,
- tables.numintersect,
- tables.numminus,
- sets.numunion,
- sets.numintersect,
- sets.numminus,
- sequences.numunion,
- sequences.numintersect,
- sequences.numminus,
- registers.numunion,
- registers.numintersect,
- registers.numminus.
- Examples:
- > tables.numunion([1, 2, 3], [4, 5, 6, 10]): # = size([1, 2, 3] union [4, 5, 6, 10])
- > tables.numintersect([1, 2, 3], [3, 4, 5]): # = size([1, 2, 3] intersect [3, 4, 5])
- > tables.numminus([1, 2, 3], [1]): # = size([1, 2, 3] minus [1])
- `tables.ishash` has been tuned and computes in O(1) time instead of O(n).
- Tweaked `augment` a little bit.
- The new C API function `agn_in` checks whether an element is part of a structure. It optionally pushes the result onto the stack.
- The new C API function `agn_hasarraypart` checks whether at least one element has been assigned to the array part of a table, in O(1) time.
- The new C API function `agn_hashashpart` checks whether at least one element has been assigned to the hash part of a table, in O(1) time.
- The new C API function `agn_numintersect` counts the number of elements in the intersection of two structures.
- The new C API function `agn_numminus` counts the number of elements in the difference of two structures.
- The new C API function `agn_numunion` counts the number of elements in the union of two structures.
- Improved the index of the Primer and Reference.
- This release has been named after the City of Vinton, Calcasieu Parish, Louisiana, close to Texas, and has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.9.6 (Jan 24, 2024)
- Added the '__index' metamethod to the `lookup` package, which is an alternative to `lookup.gettable` called with a lookup table and one of its keys.
- Added '__in' and '__notin' metamethods so that you can search for values in the subtables of a lookup table
- New `lookup.iterate` is a factory that produces iterators to traverse lookup tables. It is an alternative to `lookup.next`.
- `pipeline` has been tuned by at least 25 percent.
New in Agena 3.9.5 (Jan 22, 2024)
- The new `lookup` package implements an easy-to-use lookup table, closely related to the `bags` package
- Adapted the souces to compile again on Raspberry Pi, both 32- and 64-bit.
- Fixed error message of `next`.
New in Agena 3.9.4 (Jan 16, 2024)
- `map` and `subs` use tweaked functionality when in `descend=true` mode, avoiding re-creation of values where possible.
- When given an explicit alphabet, `strings.random` now accepts a third optional argument: `true` or `false`. When set the `true`, the default, `strings.random` will always produce really random strings, as it does now. When set to `false` and the function is subsequently called in a session, it will always produce the same sequence of random `random` strings.
- `hashes.md5` when given a string computed a wrong hash as the string was internally not split apart into chunks of 64 bytes each but was taken as one whole chunk. This has been fixed. You can reproduce the former behaviour by either passing zero or the length of the input string as a second argument. This also means if you want to determine the MD5 hash of a _file_, you must now pass a non-numeric option.
- The red-black tree package has now been fully documented, see Chapter 10.11 in the Primer & Reference.
New in Agena 3.9.3 (Jan 15, 2024)
- `prepend` has been ported to C and has become around twice as fast.
- Just for `consistency`, a new function has been introduced that does the opposite of `prepend`: `append` adds a value to the end of a structure.
- New `include` inserts one or more values to the end of a structure, not discarding multiple returns if its last argument is a function call. Note that the `insert` statement ignores all but the first return when given a function call:
- > a := []; f := << () -> 1, 2, 3 >>;
- > insert f() into a;
- > a:
- [1]
- > a := [];
- > include(a, f()):
- [1, 2, 3]
- `map` and `subs` in `descend=true` mode now accept and process sequences, registers, sets, pairs and complex numbers. Example:
- > a := seq(1, 2, reg(3, [4], seq(5:6, 7!8)))
- > map(<< x -> 2*x >>, a, descend=true):
- seq(2, 4, reg(6, [8], seq(10:12, 14+16*I)))
- > subs(7!8:1!1, a, descend=true):
- seq(1, 2, reg(3, [4], seq(5:6, 1+I)))
- When given a second argument to `tables.indices`, the returned table of integral table indices is now sorted in ascending order.
- When given any second argument to `tables.entries`, the function returns all the table values that have integral keys - in ascending order of these integral keys:
- > a := [10, 20, 30, 40, 50, -1~0, -2~-1];
- > tables.indices(a, true):
- [-2, -1, 1, 2, 3, 4, 5] true
- > tables.entries(a, true):
- [-1, 0, 10, 20, 30, 40, 50] true
- This release contains an implementation of a red-black tree, in the new plus package `rbtree`. It creates a binary search tree for numbers and assures that when inserting a number, all its elements are always stored in ascending order. The package has been added primarily to guarantee that the internal red-black tree C implementation works and is safe, otherwise it might be of use only in some special situations, this is why it currently has not been documented in the Primer and Reference and the Quick Reference.
- > import rbtree;
- > a := rbtree.new(); # create a new red-black tree
- > tostring(a): # pretty-printing
- rbtree(01F16AC0)
- > for i from 10 downto 1 do
- > rbtree.include(a, i) # insert numbers 1 to 10 in `reverse` order
- > od;
- > rbtree.entries(a): # all the elements in a, in ascending order
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- > 10 in a, 11 in a: # is ten in a - and is 11, as well ?
- true false
- > rbtree.find(a, 0): # try to find zero in a
- false
- > empty a, filled a: # is the structure empty or filled ?
- false true
- > rbtree.remove(a, 10); # remove ten from a
- > 10 in a: # ten no longer in red-black tree
- false
- > size a: # current number of elements in a
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.9.2 (Jan 10, 2024)
- With (deeply) nested tables, `map` and `subs` can recursively descend into the entire structure and map a function or substitute values with only just one call, with the new `descend=true` option:
- > map(<< x -> 2*x >>, [1, 2, 3, [4, 5, [6]]], descend=true):
- [2, 4, 6, [8, 10, [12]]]
- > subs(1:0, 6:10, [1, 2, 3, [4, 5, [6]]], descend=true):
- [0, 2, 3, [4, 5, [10]]]
- Sequences, registers, sets, pairs and complex numbers, however, are not accepted in the input structure.
- With tables as input, `map` now supports the 'reshuffle' option, removing any holes in the result before returning it. Just an example:
- > a := [1, 2, 3, 4, 5];
- > a[3] := null; # we create a hole
- > a:
- [1 ~ 1, 2 ~ 2, 4 ~ 4, 5 ~ 5]
- > map(<< x -> 2*x >>, a): # no reordering, index 3 is still not assigned a value
- [1 ~ 2, 2 ~ 4, 4 ~ 8, 5 ~ 10]
- > map(<< x -> 2*x >>, a, reshuffle=true): # return a concise table array with consecutive integral indices
- [2, 4, 8, 10]
- Hardened `map` against stack corruption in `multret=true` mode.
- When given a non-supported option, `map`, `subs, `subsop`, `select`, `remove` and `selectremove` now issue an error.
- The C API function `lua_call` now returns the number of results actually pushed onto the stack in a function call.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.9.1 (Jan 8, 2024)
- With tables, sequences, registers and strings, you can now pass the new `multret` option. When given, then contrary to the default behaviour that did not change, all elements in a structure or string are replace with _all_ the returns of the giving mapping function. Compare:
- > map(<< x -> 2*x, 0 >>, [1, 2, 3]): # the anonymous function returns both 2*x and zero, the zero is ignored
- [2, 4, 6]
- > map(<< x -> 2*x, 0 >>, [1, 2, 3], multret=true): # each element is replaced by both 2*x and zero
- [2, 0, 4, 0, 6, 0]
- With tables, the operation is destructive in the sense that all elements in the resulting structure are put into a new table array with consecutive positive integer keys starting from one, replacing the orginal indices.
- `combinat.choose` did not return all the elements when called in multiset mode (the input table contains at least one element twice or more and no second argument is given). This has been fixed.
New in Agena 3.9.0 (Jan 4, 2024)
- When indexing a table with a range `t[a to b]`, and the lower bound a greater than the upper bound b, then Agena now returns an empty table instead of throwing an error. Thus, Agena now behaves like Maple in this situation, making porting code much easier.
- The same behaviour has been implemented for sequences and registers, in the latter case a register with 16 `null` values will be returned which is equal to the `reg()` expression.
- When indexing a table with a range, such like `t[a to b]`, Agena now tries to put the subtable elements into the array part instead of the hash part of the subtable, making internal traversal easier, especially for `tables.reshuffle` which sometimes put elements in the wrong order.
- Before:
- > a := [10, 20, 30, 40, 50];
- > b := a[2 to 3];
- > tables.parts(b): # the first table is the array part, the second the hash part: the subtable was in the hash part
- [] [2 ~ 20, 3 ~ 30]
- After:
- > a := [10, 20, 30, 40, 50];
- > b := a[2 to 3];
- > tables.parts(b): # the subtable now is in the array part
- [2 ~ 20, 3 ~ 30] []
- With a table array, by passing the new 'reshuffle' option, both `subs` and `subsop` will no longer leave holes when deleting values from it, so a subsequent call to `tables.entries` is unnecessary. Compare:
- > subs(2:null, [1, 2, 3]):
- [1 ~ 1, 3 ~ 3]
- > subs(2:null, [1, 2, 3], reshuffle=true):
- [1, 3]
- The `newarray` option for functions `map`, `select`, `remove, `selectremove` has been replaced by the `reshuffle` option, providing the same functionality. The old name `newarray`, however, is still supported so that you do not have to change your code.
- The new function `tables.isnullarray` checks whether a table consists of an array part only and whether at least one of its values is `null`.
- The new function `tables.hashole` checks whether the array part of a table contains at least one `null` value, i.e. a hole. The table may or may not have a hash part. An example:
- > a := [10, 20, 30, 40, 50 ~ 0]
- > tables.hashole(a):
- false
- > a[3] := null
- > tables.hashole(a):
- true
- `tables.reshuffle` can now remove one or more holes from the array part of a table without moving the values in the hash part to the array part, by passing any second argument. See the difference:
- > a := [10, 20, 30, 40, 50 ~ 0]
- > a[3] := null # remove a[3] = 30, leave a hole in the array part
- > tables.reshuffle(a) # hash part element a[50] is added to end of array part
- > a:
- [10, 20, 40, 0]
- > a := [10, 20, 30, 40, 50 ~ 0]
- > a[3] := null # remove a[3] = 30, leave a hole in the array part
- > tables.reshuffle(a, true) # remove hole in array part only, leave hash part element a[50] untouched
- > a:
- [1 ~ 10, 2 ~ 20, 3 ~ 40, 50 ~ 0]
- New `combinat.choose` constructs the combinations of table elements; it is a clone of the Maple function of the same name:
- > combinat.choose([1, 2, 3]):
- [[], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]]
- > combinat.choose([1, 2, 3], 2):
- [[1, 2], [1, 3], [2, 3]]
- `combinat.cartprod` now only returns a generating function if you pass any non-null second argument. Otherwise it now returns the complete Cartesian product with just one call. An example:
- > combinat.cartprod([[1, 2, 3], [30], [50, 100]]):
- [[1, 30, 50], [1, 30, 100], [2, 30, 50], [2, 30, 100], [3, 30, 50], [3, 30, 100]]
- With sequences and registers, you can now pass negative positions k to `purge`, deleting the k'th element from the end of the structures.
- There was a bug with the colon pretty-printer, that did not worsely affect Agena evaluating code: when printing the result of an assignment statement at the prompt, the expression to the right of the `:=` token had been evaluated twice:
- > a := 0;
- > a := a + 1: # should have been 1, but the pretty-printer output:
- The assignment statement, however, had been correctly executed:
- > a:
- This bug has been fixed.
- The new C API function `agn_tabpurge` deletes a value from the array part of a table that does not include `null` without leaving a hole.
- The release has been named after the City of Rayne, Acadia Parish, Louisiana.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.7.8 (Jan 1, 2024)
- Improved error messages of various operators and functions.
- New `hashes.sha256` computes the SHA256 hash.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.7.7 (Dec 31, 2023)
- foreach` now has a third flavour that resembles the `reduce` function and thus makes the operator more generic and versatile: By passing an interval with an optional step size, a two-parameter accumulator function and an initialiser of any type, you can create short one-liners.
- Two examples: To compute the tenth factorial 10! = fact(10) issue
- foreach(true, 1, 10, 1, << x, a -> a*x >>, 1):
- 3628800
- In this example, the operator receives the range [1, 10] and step size 1. The accumulator function with its first argument receives the iteration value and with its second argument the accumulator which is initialised to 1 (last argument). The function returns the updated accumulator.
- To compute a list of the first ten factorials, enter:
- foreach(true, 1, 10, proc(x, a) is insert a[size a]*x into a; return a end, [1]):
- 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
- The first value in the return is the initialiser - you can provide a more sophisticated function that omits it from the result.
- Compared to `reduce` and `fold`, the new feature is great to save a lot of memory for you pass only a left and right border and a step size and not a structure of - often many - individual values.
- foreach` now accepts fractional start and step values, uses Kahan-Babuska summation only if the start or the step values are fractional, and can `count backwards` if the start value is greater than the stop value.
- To avoid confusion, `stats.poissonpdf` has been renamed to `stats.poisson`. An alias has been provided to ensure backward-compatibility.
- stats.poisson` accepted negative first arguments. It also returned a wrong value if both arguments had been zero. All has been fixed.
- stats.logistic` now returns a real result instead of `undefined` if its third argument is non-positive.
- The `beta` function returned `undefined` instead of a real result in various situations. This has been fixed.
- tonumber` now returns `fail` if it received a value that could not be converted to a number, so it now behaves as described in the Primer & Reference. Exception: With a non-convertible string, the function still returns this string.
- Extended the test cases for the `stats` package and laid the foundation for three and four argument mass test cases.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.7.6a (Dec 24, 2023)
- Just updated the documentation and test cases, no further changes. You can also individually download the updated documentation from the `Manuals` subfolder.
New in Agena 3.7.5 (Dec 20, 2023)
- The new `stats.beta` function implements Maple's function of the same name and computes the probability density function 1/beta(nu1, nu2) * x^(nu1-1) * (1-x)^(nu2-1) of the Beta distribution.
- New `stats.negbinompdf` implements Maple's negativebinomial function and computes the probability density function equal to binomial(n + x - 1, x) * p^n * (1 - p)^x.
- `stats.logistic` in its new multi-argument form computes the probability density function of the Logistic[a, b] distribution, as implemented in Maple. Likewise, the new multi-argument form of `stats.laplace` computes the probability density function of the Laplace[a, b] distribution, also as implemented in Maple.
- New `math.gammasign` returns the sign of the gamma(x) function, i.e. -1 if x < 0 and odd(entier(x)), and 1 otherwise. When given multiple numbers, the respective `gamma signs` are multiplied with each other.
- With negative real arguments, `math.beta` and thus `beta` could return `undefined` although real solutions exist or it could return the result with the wrong sign. This has all been fixed.
- `instr` mostly did not work if the second argument was a set of strings, claiming it found non-strings. Also with sets, the function could corrupt the stack. This has all been fixed.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.7.3 (Dec 16, 2023)
- New `math.lnbinomial` and `long.lnbinomial` compute the natural logarithm of the binomial coefficent, avoiding overflow with large values.
- `stats.binomd`, `stats.binompdf`, `stats.poissond` and `stats.poissonpdf` overflowed with larger arguments, returning `undefined` in such cases. This has been fixed.
- `binomial` and thus `combinat.numbcomb` overflowed with a larger negative integral first argument or with large fractional arguments. This has been fixed, too.
- The `qmdev` operator now uses Kahan-Babuska summation for better internal round-off error prevention. The `qmdev` metamethod of the `numarray` package does so, as well.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.7.2 (Dec 13, 2023)
- stats.binomd`, `stats.poisson`, `stats.ad`, `stats.md`, `stats.ios`, `stats.rownorm`, `stats.gini`, `stats.acf`, `stats.acv`, `linalg.dotprod`, `linalg.det`, `linalg.mmul`, `linalg.trace`, `math.compose`, `numarray/qmdev` metamethod and `calc.eps` use Kahan-Babuska summation for better internal round-off error prevention
- New `math.kbadd` conducts Kahan-Babuska summation to be used primarily in iterations if advanced round-off error prevention is needed while summing up Agena numbers
- math.ndigits` returned wrong results with the integral part of Agena Numbers. This has been fixed
- environ.kernel` returns the number of digits in the floating point mantissa for C data long doubles in the new field 'longmantdigs' and the largest possible exponent value in C long doubles in the new field 'longmaxexp'. The values vary across platforms
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks
New in Agena 3.7.1 (Dec 11, 2023)
- The new two-argument variant of `calc.Psi` computes the digamma, trigamma and tetragamma functions:
- > calc.Psi(0, Pi): # digamma = calc.Psi(Pi)
- 0.97721330794201
- > calc.Psi(1, Pi): # trigamma
- 0.37424376965454
- > calc.Psi(2, Pi): # tetragamma
- 0.13854737032139
- The new `member` function emulates Maple's function of the same name and checks whether an element is included in a table, sequence or register. If there is a hit, it returns `true` plus the position of the first hit in the structure as a second result, otherwise it returns `false` and `null`. Examples:
- > member(10, [0, 5, 10, 10, 0]):
- true 3
- > member(undefined, [0, 5, 10, 10, 0]):
- false null
- The function is around 40 percent faster than related `whereis` if you just need the index of the first hit. Note that with respect to `whereis`, the parameters are in reverse.
- Tweaked various `calc` functions a little bit: `calc.Ei`, `calc.Si`, `calc.Ci`, `calc.Shi`, `calc.Chi`, `calc.Psi`, `calc.dilog`, `calc.fresnelc`, `calc.fresnels`, `gamma` (OS/2 and DOS), `calc.Ai`, `calc.Bi`, `calc.zeta`, `calc.En`, `calc.igamma`, `calc.igammac`, `calc.ibeta` and `calc.invibeta`.
- `long.lnabs` did not compute the absolute value before determining the natural logarithm. This has been fixed.
- In the Primer and Reference, the description of the `numarray` package has been improved by various examples.
- The Proton editor schema file was corrupt. This has been fixed.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.7.0 (Dec 7, 2023)
- The following former plus packages have been integrated into the core interpreter: `bags`, `calc`, `linalg`, `stats`, `long`, `xbase`, `llist`, `ulist`, `dlist`, `factory`, `bytes`, `sema`, `numarray` and `utf8`.
- Thus they are immediately available at start-up and you do not have to use the `import` statement or the `readlib` function any longer to load them.
- The following combinatorical functions have been moved to the new `combinat` package:
- calc.bernoulli` moved to `combinat.bernoulli`,
- calc.euler` moved to `combinat.euler`,
- stats.bell` moved to `combinat.bell`,
- stats.cartprod` moved to `combinat.cartprod`,
- stats.numbcomb` moved to `combinat.numbcomb`,
- stats.numbpart` moved to `combinat.numbpart`,
- stats.numbperm` moved to `combinat.numbperm`.
- In all cases aliases have been provided for backward-compatibility.
- New `combinat.stirling1` and `combinat.stirling2` compute the Stirling number of the first and second kind, respectively. The equivalent function `math.stirnum` has been deprecated but an alias has been provided to ensure backward-compatibility.
- New `combinat.catalan` computes the n-th Catalan number.
- The deprecated `stats.sum` function has been removed. You may use `stats.sumdata` or the `addup` operator.
- Deprecated `llist.listtotable` has been deleted. Use `llist.totable` instead.
- Deprecated `bytes.getwordsofdouble` has been removed. Use `bytes.numwords` instead.
- Deprecated `bytes.gethighofdouble` has been removed. Use `bytes.numhigh` instead.
- Deprecated `bytes.getlowofdouble` has been removed. Use `bytes.numlow` instead.
- Deprecated `bytes.setwordsofdouble` has been removed. Use `bytes.setnumwords` instead.
- Deprecated `bytes.sethighofdouble` has been removed. Use `bytes.setnumhigh` instead.
- Deprecated `bytes.setlowofdouble` has been removed. Use `bytes.setnumlow` instead.
- Deprecated `numarray.get` has been removed. Use `numarray.getitem` instead.
- Deprecated `numarray.put` has been removed. Use `numarray.setitem` instead.
- The release has been named after the place of Carlyss in Calcasieu Parish, Louisiana.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.6.3 (Dec 6, 2023)
- `erf` has been extended to compute the integral of the Gaussian distribution from z to w, with erf(z, w) = erf(w) - erf(z). Complex numbers are supported, too.
- New `math.chi` implements the piecewise indicator function.
- New `stats.binompdf` determines to the binomial probability density.
- New `stats.binomd` simplifies to the cumulative probability binomial distribution function.
- New `stats.poissonpdf` calculates the Poisson probability density.
- New `stats.poissond` implements the cumulative probability Poisson distribution function.
- `stats.numbcomb` has been reimplemented in C and has become 30 percent faster.
- `stats.numbperm` has been reimplemented in C and has become 40 percent faster.
- New `utils.numiters` returns the number of iterations in the interval [a, b], with a <= b and with an optional positive step size, which is one by default. The result is equal to int(|b - a|/step) + 1.
New in Agena 3.6.2 (Nov 30, 2023)
- Under heavy load and in Linux 64-bit environments only (ARM & Intel/AMD), sporadic stack corruption has been observed during the regression tests causing confusing error messages but no memory leaks or segmentation faults. This has been solved by raising the default minimum stack size from 40 to 128 slots on all platforms, including the 32-bit editions of Agena. It is generally advised to install this fix. You can query the setting with
- > environ.kernel('minstack'):
- 128
- The minimum stack size cannot be changed at runtime, but only by re-compiling the sources (see LUA_MINSTACK in agena.h).
- The new `addup` keyword has been added to AgenaEdit.
- AgenaEdit for Solaris and Debian now use the latest Agena version.
New in Agena 3.6.0 (Nov 28, 2023)
- The new operator `addup` sums up all elements in a table, sequence, register or userdata, optionally dividing by a number or the size of the distribution, or applying a function on each element before adding it to the sum, or calculating the p-moment. In arithmetic mean mode, the operator is 45 percent faster than `stats.amean`, and in p-moment mode 15 percent faster than `stats.moment`.
- The `qmdev` and `mulup` operators now call metamethods exactly as `sumup`, `qsumup` and all the other operators do: they no longer ignore a metamethod if it is attached to a table, sequence or register.
- The `mulup` and `foreach` operators could have thrown out-of-memory errors. This has been fixed.
- stats.mean`, `stats.qmean` and `stats.kurtosis` have been tuned by twelve percent with tables and sequences and 40 percent with numarrays.
- stats.trimmean` has become eight percent faster.
- With numarrays, `stats.var` has become seven times faster.
- Problems with sporadic `missing entry point` issues observed in Windows 11 - and only there - when initialising the `mapm` package may hopefully have been solved.
- The release has been named after the place Charon in Vermilion Parish, Louisiana (and Pluto's largest moon).
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.5.6 (Nov 24, 2023)
- The `mulup` and `qmdev` operators can now call metamethods for any datatype
- `statsmode`, `statsspread`, `statsskewness` and `statskurtosis` now support numarrays
- The `sumup`, `qsumup`, `mulup` and `qmdev` operators can now process numarrays
- New `numarraytotable` returns a table with all the numbers stored to a numarray
- Tuned `calcbernoulli` a little bit
- `statsbell` crashed Agena when given a large argument This has been fixed
- Patched `statstrimmean` which returned wrong results when given a table
- The statistics test cases have been extended
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks
New in Agena 3.5.5 (Nov 23, 2023)
- The `times` operator, `registers.new`, `sequences.new` and `tables.new`, `memfile.map`, `tuples.map`, `utils.speed`, `xbase.header` plus the factories produced by `factory.anyof` and `factory.pick` have all been hardened against stack corruption.
- The `copy` operator did not deep-copy registers that reside in the array part of tables. This has been fixed.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.5.3 (Nov 13, 2023)
- `regex.find` and `regex.match` have become three times faster and also use much less memory, thus preventing out-of-memory errors that might occur in Windows 11, but not in other Windows versions or other operating systems.
- New `dual.tostring` converts a dual number to a string.
- As a preparatory measure for the future, `debug.setstore` can now set an internal storage table to a procedure implemented in C. It still allows to add new entries to an existing storage table, regardless whether the function has been implemented in Agena or C. The function now also allows to delete storage tables and has also been implemented in C.
- The new C API function `agn_setstorage` sets a storage table to a procedure or deletes it. It also allows to add entries to an existing storage table.
- A few changes under the hood without influence on functionality.
- Improved the documentation a little bit.
- Extended the test cases.
- The Mac OS X installer now includes the latest version of AgenaEdit.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.5.2 (Nov 6, 2023)
- New `mapm.sinhcosh` returns both the real hyperbolic sine and hyperbolic cosine in one call.
- New `mapm.sec` computes the real secant, `mapm.cot` computes the real cotangent and `mapm.csc` the real cosecant.
- New `mapm.sech` computes the real hyperbolic secant, `mapm.coth` computes the real hyperbolic cotangent and `mapm.csch` the real hyperbolic cosecant.
- New `mapm.sinc`, `mapm.cosc` and `mapm.tanc` compute the real un-normalised cardinal sine, cosine and tangent.
- New `mapm.csec` computes the comple secant, `mapm.ccot` computes the comple cotangent and `mapm.ccsc` the comple cosecant.
- New `mapm.csech` computes the comple hyperbolic secant, `mapm.ccoth` computes the comple hyperbolic cotangent and `mapm.ccsch` the comple hyperbolic cosecant.
- New `mapm.csinc`, `mapm.ccosc`, `mapm.ctanc` compute the comple un-normalised cardinal sine, cosine, tangent.
- New `mapm.random` generates a random real mapm number, and `mapm.randomseed` sets the seed.
- The ``, `even` and `odd` operators now support real mapm numbers.
- The pretty-printer has been fied for negative imaginary parts.
- The `-` operator when applied to real mapm numbers could corrupt the stack. This has been fied.
- Arithmemtic binary operators and relational operators, both in the real and comple domain, sometimes corrupted the stack. This has been fied.
- `mapm.log2` has become 50 percent faster.
- Etended the mapm test cases.
- Cleansed the code to avoid some compiler warning messages in Linu and Solaris.
- This release has been Valgrind-checked on 86 and AMD64 Linu to ensure there are no internal errors or memory leaks.
New in Agena 3.5.0 (Oct 31, 2023)
- The `mapm` package for arbitrary-precision math now includes various operators and functions that work in the complex domain:
- > import mapm;
- > mapm.xdigits(17); # precision
- > x := mapm.cnumber(1, 2); # define x = 1 + 2*I
- > y := mapm.cnumber(3, 4); # define y = 3 + 4*I
- Addition:
- > x + y:
- mapm.cnumber(4.00000000000000000, 6.00000000000000000)
- Convert the result to a complex Agena number:
- > mapm.ctocomplex(ans):
- 4+6*I
- Determine the absolute value, the return is a real mapm number:
- > abs(x):
- 2.23606797749978970
- Get the natural logarithm:
- > ln(x):
- mapm.cnumber(0.80471895621705019, 1.10714871779409050)
- Get real and complex part of the previous calculation, to be returned as real mapm numbers:
- > real(ans), imag(ans):
- 0.80471895621705019 1.10714871779409050
- In OS/2 and DOS `arcsinh` has been tuned, also benefitting `arcsin` and `arccos`.
- Tested the Windows installer for any missing dependencies on a fresh Windows 2000 installation.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
- The release has been named after the place of Amelia, Southern Louisiana.
New in Agena 3.4.10 (Oct 7, 2023)
- The multi-line colon pretty-printer has been further refined and its error messages have been improved. It now rejects previously accepted invalid input such as
- > sin(:
- > Pi/2)
- Error: invalid or ambiguous syntax near `:`
- and just accepts expressions and statements like this:
- > sin(
- > Pi/2):
New in Agena 3.4.9 (Oct 5, 2023)
- The colon facility to easily print results at the console now also works with multi-line expressions and statements, for example
- > sin(
- > Pi/2) + ln
- > (2):
- 1.6931471805599
- will no longer throw a syntax error or get the input stuck.
- `strings.fields` can now convert a string representing a complex number to that complex number when given the `convert=true` option. The string value must be of the form `a+I*b`.
- In-place sorting has become twelve percent faster when (and only when) passing an ordering function as the last argument to `sort`. The ordering function must now be strict, e.g. pass
- > sort(tbl, << x, y -> strings.strverscmp(x, y) < 0 >> ); # now: less than zero
- instead of
- > sort(tbl, << x, y -> strings.strverscmp(x, y) <= 0 >> ); # then: less than _or equals_ zero
- The new API C function `agnL_strtocomplex` tries to convert a string representing a complex number to that complex number.
New in Agena 3.4.8 (Oct 3, 2023)
- You can now pass a string to `linalg.matrix` for easier input: The row vectors are separated by commas and the vector components by one or more white spaces. Carriage returns and newlines, if any, will be ignored. So, for example
- > linalg.matrix('1 2 3, 4 5 6, 7 8 9'):
- results in
- [ 1, 2, 3 ]
- [ 4, 5, 6 ]
- [ 7, 8, 9 ]
- Likewise, `linalg.vector` now also accepts strings with the vector components separated by one or more white spaces. Example:
- > linalg.vector(' 1 2 3 '):
- [ 1, 2, 3 ]
- The Mac OS X installer did not include all components of AgenaEdit. This has been fixed.
New in Agena 3.4.7 (Oct 2, 2023)
- The new `foreach` operator traverses a numeric range, applies a univariate function on each intermediate value and puts the result into a given structure.
- With a fractional start value or fractional step size, the operator uses Kahan-Babuska summation to prevent round-off errors.
- If the given structure already includes elements, they are not overwritten, and the function values are appended instead.
- The operator allows to omit the step size (defaulting to one) or the structure (in this case returning a table of function values).
- The operator is 25 percent faster than `tables.new` or `sequences.new`, and twice as fast as the statement sequence given above.
- If you pass a number, preferably zero, as the last argument, the operator computes the sum of all function values, also applying Kahan-Babuska summation:
- # Pi approximation by Indian mathematician and astronomer Madhava of Sangamagrama, 14th century AD: sqrt(12)*foreach(0, 25, << k -> (-3)^(-k)/(2*k + 1) >>, 0): 3.1415926535898
New in Agena 3.4.6b (Sep 28, 2023)
- AgenaEdit now supports the following command-line options:
- Usage: agenaedit [options] [file to be opened]
- F number set text font size to given number, default is 14
- a ignore AGENAPATH environment variable
- d print debugging information during startup and within a session
- h, -? display this help
- n do not run initialisation file(s) `agena.ini`
- p path sets <path> to libname, overriding default libname initialisation
- r name readlib library <name> (no quotes needed)
- x do not run main library file lib/library.agn
- B throw syntax error when numeric constants are too big
- C allow constants to be overwritten
- D number set number of digits in output of floats to number (1 to 17)
- Check new menu item `Help/Command-Line Options` for further information.
- Added the experimental AgenaEdit menu item `Edit/Preferences/Font Size` to change the text font size. Setting the font size via command-line option from a shell, however, for example
- > agenaedit -F 20
- may work better.
- In Solaris, the AgenaEdit background colour of the text input field has been set to white instead of grey.
- The Debian x86 version of AgenaEdit crashed. This has been fixed.
New in Agena 3.4.6 (Sep 26, 2023)
- AgenaEdit is now available in the i386 and x64 Debian distributions, and in the Solaris x86 edition.
- Beautification of AgenaEdit for all supported platforms.
- When the `mpf` library had been invoked and later on the `restart` statement was run, Agena crashed. This has been fixed.
- The Solaris dynamic link libraries have been updated and rebuilt.
New in Agena 3.4.5c (Sep 20, 2023)
- Some fixes to AgenaEdit for Windows:
- Changed colour and style of comments to grey and Courier font for better formatting and readability.
- Aligned `Break`, `Restart` and `Close` buttons of the execution screens around the centre.
- Further code streamlining of the Agena sources to get AgenaEdit compiled in Solaris, Linux and Mac OS X, especially due to previous clashes between ANSI C and C++ source files.
New in Agena 3.4.5b (Sep 19, 2023)
- Various extensions and fixes to AgenaEdit for Windows:
- Migrated the code from FLTK-1.1.10 to FLTK-1.3.8.
- Formerly missing dependency file `libstdc++-6.dll` is now included in the Windows distributions.
- Added line numbers to the left of the editor window.
- Via new menu item `Edit/Preferences` you can switch on or off word wrapping and display of line numbers.
- Structures and complex numbers are now being displayed properly and in full detail.
- Added a `Close` button to the execution screens.
- When choosing the `Run/Execute selected` menu item, the `Break` and `Restart` buttons were not displayed. This has been fixed.
- In the `Help/System Information` window, the home directory is now being given, again.
New in Agena 3.4.5a (Sep 18, 2023)
- In Windows only, reintroduced AgenaEdit, a simple light-weight editor with syntax highlighting that runs your code. Check Chapter 3.2 of the Primer and Reference for a short introduction.
- Improved the description on how to install the portable Windows version.
- In the Windows distributions the documentation was not up-to-date. This has been fixed.
- Streamlined the code, no functional changes.
- Fixed a Windows compilation batch file that accidently deleted the PATH environment variable from the current Windows shell session. It did not delete or modify the PATH settings in the registry.
New in Agena 3.4.5 (Sep 9, 2023)
- When Agena was in debug mode, a lot of stray formatting specifiers have been printed on screen. This has been fixed. Duplicate debug messages have also been removed, too.
- Potential issues with complex arguments and resulting wrong results of `besselj` (all platforms), `bessely` (all platforms) and `cosc` (all platforms except OS/2, DOS and Solaris) have been fixed.
- In OS/2, complex math generally has been tuned by five percent.
- The OS/2 makefile has been completely reworked and now also produces a DLL file which is included in the WarpIN installer from now on.
New in Agena 3.4.4 (Sep 3, 2023)
- xbase.writenumber`, `xbase.writefloat`, `xbase.writedouble`, `xbase.writecomplex`, `xbase.writebyte` and `xbase.write` could write truncated content to a dBASE file, resulting in wrong field sizes. This bug has been fixed
- The new C API function `agnL_pushvstring` takes one or more strings and pushes their concatenation onto the top of the stack
- The new C API function `agnL_strtonumber` tries to convert a string in the stack to a number and if successful replaces that string with that number
- The new C API function `agnL_strunwrap` removes an enclosing substring from a string in the stack
- Cleansed the code to prevent compiler warnings
- Improved the index of the Primer and Reference
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks
New in Agena 3.4.3 (Aug 31, 2023)
- The `import` statement now optionally prints various debugging information while it is initialising a library. Just set environ.kernel(debug = true) before.
- Examples:
- import ads
- Processing library: ads.
- ads is an external (plus) package.
- Checking path C:agenasrc.
- Checking C library file C:agenasrc/ads.dll.
- C:agenasrc/ads.dll not present.
- Checking agn library file C:agenasrc/ads.agn: not present.
- Checking path c:/agena/lib.
- Checking C library file c:/agena/lib/ads.dll.
- c:/agena/lib/ads.dll successfully initialised.
- Checking agn library file c:/agena/lib/ads.agn: found.
- All successful, now registering ads.
- import math
- Processing library: math.
- math is a standard library.
- Nothing to be done.
- In Windows, new `os.getloadeddlls` returns Agena's current process id. It also returns all the DLLs along with their absolute paths used by the interpreter. You can pass a valid Windows process id to explore the modules loaded by another application, as well.
- In Windows, new `os.getwinsysdirs` retrieves both the Windows directory and the system directory.
- When given one or more relative paths at startup via the command-line -p option or the AGENAPATH environment variable, Agena could not find external libraries. This has been fixed.
- Potential duplicate initialisations of libraries by the `import/alias` statement (aka function `initialise`) are now being prevented.
- The portable Windows version now includes the batch file `run.bat`. It allows to easily run the interpreter without having to manually change environment variables, etc. Check the `readme.w32` file at the root of the ZIP archive for further information.
- Since some plus packages compiled with MinGW/GCC 10.2.0 such as the MPFR binding `mpf` crash the interpreter on Windows platforms prior to Windows 7 or 2008 Server, it has been decided to entirely switch back to GCC 9.2.0 to ensure 100 percent compatibility and stability.
- Some issues with the Windows NSIS installer not properly storing some few programme icons have been fixed.
New in Agena 3.4.2 (Aug 29, 2023)
- In the `mpf` package, a binding to the MPFR library with some extensions, division by zero now returns `undefined` instead of `infinity`, same with the `recip` operator.
- The `recip` operator has become 25 percent faster, `cube` 13 percent faster and `square` twice as fast.
- New `mpf.hypot4` returns sqrt(x^2 - y^2), new `mpf.pytha` x^2 + y^2 and new `mpf.pytha4` x^2 - y^2.
- New `mpf.root` computes the n-th root.
- New `mpf.arccsch` computes the inverse hyperbolic cosecant.
- New `mpf.arcsech` computes the inverse hyperbolic secant.
- New `mpf.arccoth` computes the inverse hyperbolic cotangent.
- New `mpf.relerror` computes the relative difference |b - a|/a.
- New `mpf.cmpd` compares an MPFR value with an Agena number.
- When initialised multiple times in the same Agena session, the `mpf` package did not free all allocated memory. This has been fixed.
- The `mpf` package is now fully described in the Quick Reference. Also added all `mpf` functions to the index of the Primer & Reference.
- New `os.islinux386` checks whether the Agena executable has been compiled on 32-bit x86 Linux.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.4.1 (Aug 27, 2023)
- `os.islinux` and `os.ismac` have been ported to C and have become 525 times faster.
New in Agena 3.4.0 (Aug 24, 2023)
- New `os.ismac` checks whether Agena is being run on Mac OS X (Darwin).
- The `mpf` package is now bound to the latest MPFR 4.2.1 library edition.
- The `square`, `cube` and `recip` operators now support MPFR numbers.
- Added functions `mpf.sech` (hyperbolic secant), `mpf.csch` (hyperbolic cosecant), `mpf.coth` (hyperbolic cotangent), `mpf.arccosh` (inverse hyperbolic cosine), `mpf.arcsinh` (inverse hyperbolic sine) and `mpf.arctanh` (inverse hyperbolic tangent).
- Added constants `mpf.nought`, `mpf.one`, `mpf.two`, `mpf.three`, `mpf.half`, `mpf.quarter`, `mpf.tenth`, etc. See Chapter 11.5, p. 544 for all of them.
- mpf.new` and `mpf.tostring` have been patched to prevent segmentation faults when given or converting `+/-infinity` and `undefined`.
- The `copy` operator could corrupt the internal stack and thus crash Agena. This has been fixed.
- calc.isdiff` often returned wrong results, especially with points where the graph of a function is steep. This has been fixed by introducting a more adaptive approach. The function may still return wrong results around poles, but has been significantly improved compared to the former version. If no `eps` option is given, the function now uses the setting of Eps for comparison at a point x instead of varying math.eps(x).
- The Solaris installer did not contain the latest version of the `mpf` package. This has been fixed.
- Extended the regression test cases.
- The release has been named after the City of Eunice, Louisiana.
New in Agena 3.3.5 (Aug 20, 2023)
- New `calc.intcc` integrates a univariate function over an interval, using Clenshaw-Curtis-Quadrature. The function is almost thrice as fast as `calc.intde` with equal quality.
- `calc.intde` now issues an error if the left boundary is greater than or equals the right boundary. The function has also become 40 percent faster if you do not change the default epsilon value 1e-15, passed as the fourth argument.
- New `long.inverf` implements the inverse error function.
- The `$$` operator which checks whether at least one element in a structure satisfies a condition could corrupt the stack, thus returning wrong results or even throwing segmentation faults. This has been fixed.
- Extended the regression test cases.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.3.4 (Aug 19, 2023)
- The accuracy of the second derivative computed by `calc.diff` has been increased 4-fold. The quality of the third derivative has been slightly improved
- calc.diff` can now compute the fourth and fifth derivative
- calc.differ` has been extended to compute the fourth and fifth derivative and significantly improved by internally calling `calc.cheby` if the point to be evaluated is not near an undefined realm, or by calling `calc.diff` with higher-order derivatives (> 3) if the the point is near an undefined realm
- mapm.xerf` and thus also `mapm.xerfc` have become 35 % faster
- New `zx.LGAM` implements the logarithmic gamma function
- zx.GAM` has been fixed to prevent internal division by zero
New in Agena 3.3.3 (Aug 13, 2023)
- Extended the `mapm` package for arbitrary-precision real math:
- New `mapm.xint` truncates a float, that is rounds it towards zero to the nearest integer.
- New `mapm.xarcsec` and `mapm.xarccsc` implement arcsecant and arccosecant.
- The `int` and `arcsec` operators support MAPM numbers.
- New `mapm.xhypot4` computes sqrt(a^2 - b^2).
- Added `mapm.xrecip` which is just an alias to `mapm.xinv`. Also added functions `mapm.xcube` and `mapm.square` which work like the `square` and `cube` metamethods.
- Added new test cases and improved description of the package in the Primer and Reference.
- Miscellaneous:
- The OS/2 installer is shipped with more recent gmp, mpfr, expat, history and readline dependency DLL files.
- On x86 Linux and Raspberry Pi ARM, when statically linked, Agena libraries now bind against the latest versions of: expat-2.5.0, fontconfig-2.14.2, freetype-2.13.1, gmp-6.3.0, mpfr-4.2.0, libiconv-1.17 and libpng-1.6.40.
- On x86 Solaris, when statically linked, Agena libraries now bind against the latest versions of: expat-2.5.0, gmp-6.3.0, mpfr-4.2.0, libiconv-1.17 and libpng-1.6.40.
- This release has been Valgrind-checked on x86 and AMD64 Linux to ensure there are no internal errors or memory leaks.
New in Agena 3.3.2 (Aug 12, 2023)
- `calc.cheby` can now approximate the sixth, seventh and eighth derivative of a function:
- > import calc
- > f := calc.cheby(<< x -> ln x >>, 3, 7, 30, deriv = 6); # for 3 <= x <= 7
- > f(5): # 6th derivative of ln(x) <=> -120/x^6, at x=5, exact value is -0.00768:
- 0.0076800000481259
- `calc.chebycoeffs` has been ported to C, has become thrice as fast and also more accurate as it is internally computing with 80-bit floating-point numbers. See next point for an example.
- The new function `calc.chebygen` takes a table of Chebyshev coefficients and generates a factory computing approximations:
- > coeffs := calc.chebycoeffs(<< x -> ln x >>, 3, 7, 30):
- [1 ~ 3.1335984739448, 2 ~ 0.41742430504416, 3 ~ -0.0435607626104, ..., domain ~ 3:7]
- Return a factory computing the sixth derivative of ln(x) = -120/x^6:
- > f := calc.chebygen(coeffs, deriv = 6);
- Evaluate derivative at x=5:
- > f(5):
- 0.0076800000481259
- So by combining `calc.chebycoeffs` with new `calc.chebygen` you actually emulate `calc.cheby`, but have much more control about the evaluation process.
- The `import` statement often issued one and the same error message multiple times when trying to initialise the same corrupt or incompatible DLL/so library. This has been fixed.
- Minor tweak to `zx.genseries`.
New in Agena 3.3.1 (Aug 7, 2023)
- Sped up initialisation of the main library file.
- `os.list` has been tweaked by avoiding internal duplicate buffer operations.
- In Linux, `os.now`, `os.date` and `os.time` now return actual milliseconds.
- Corrected error messages of the `$$` operator.
- The Windows installers include the latest DLLs for zlib, libiconv, libmpfr, libgmp, libfreetype, libexpat and libpcre and successfully set up Agena on Windows 2000 SP4, Windows 2003 Server, Windows XP SP3, Vista, Windows 7, 8.1, 10 and 11.
New in Agena 3.3.0 (Aug 7, 2023)
- The `@` and `$` operators have become 25 percent faster.
- In Windows, by adapting and compiling the sources with GCC 10.2.0, at least numeric `for` loops have become five percent faster.
- `zx.reduce` has been tuned by eight percent.
- Added `fastmath.floor` which is eight percent faster than the `floor` function. It is always recommended to use the `entier` operator which is much faster and 100 percent portable across platforms.
- The release has been named after the Shrine of Texas Liberty in San Antonio, the Alamo.
New in Agena 3.3.0 RC 2 (Aug 6, 2023)
- This is a series of release candidates primarily to get Agena faster on Windows by modifying and compiling the sources with GCC 10.2.0 instead of 9.2.0.
- At least numeric `for` loops have become five percent faster with GCC 10.2 so far.
- All the release candidates uploaded have been checked with Valgrind to ensure there are no internal errors or memory leaks and with all the regression tests successfully done. Most of the tests have been run on Windows 2000 Service Pack 5, OpenSUSE 10.3 and concurrent ArcaOS to guarantee integrity. Windows 2000 Service Pack 5 is also being used to test the NSIS installers.
- There will be no further updates to this README file, to spare you of any automatic Sourceforge info messages. Just check the change.log file in the binary and source distributions if you are interested.
- `zx.reduce` has been tuned by eight percent.
- Added `fastmath.floor` which is eight percent faster than the `floor` function. It is always recommended to use the `entier` operator which is much faster and 100 percent portable across platforms.
- The release has been named after the Shrine of Texas Liberty in San Antonio, the Alamo.
New in Agena 3.3.0 RC 1 (Aug 5, 2023)
- This is a series of release candidates primarily to get Agena faster on Windows by modifying and compiling the sources with GCC 10.2.0 instead of 9.2.0.
- At least numeric `for` loops have become five percent faster with GCC 10.2 so far.
- All the release candidates uploaded have been checked with Valgrind to ensure there are no internal errors or memory leaks and with all the regression tests successfully done. Most of the tests have been run on Windows 2000 Service Pack 5, OpenSUSE 10.3 and concurrent ArcaOS to guarantee integrity. Windows 2000 Service Pack 5 is also being used to test the NSIS installers.
- There will be no further updates to this README file, to spare you of any automatic Sourceforge info messages. Just check the change.log file in the binary and source distributions if you are interested.
- `zx.reduce` has been tuned by eight percent.
- Added `fastmath.floor` which is eight percent faster than the `floor` function. It is always recommended to use the `entier` operator which is much faster and 100 percent portable across platforms.
- The release has been named after the Shrine of Texas Liberty in San Antonio, the Alamo.
New in Agena 3.2.1 (Aug 2, 2023)
- Internal argument reduction of trigonometric functions has been tuned, speeding the functions up by five to nine percent: among them `sin`, `cos`, `tan`, `math.sincos` and many other functions, e.g. those computing in the complex domain.
- `tan` now properly treats subnormal real numbers.
New in Agena 3.2.0 (Jul 30, 2023)
- New `invgamma` computes the inverse gamma function 1/gamma(x).
- New `calc.gammainc` computes either the upper or lower incomplete gamma function.
- New `stats.gammacdf` realises the gamma cumulative distribution function.
- New `stats.gammapdf` implements the gamma distribution probability density function.
- New `stats.F` computes the F distribution, new `stats.Fc ` the complemented F distribution and new `stats.invF` the inverse of the complemented F distribution.
- New `calc.expn` computes the exponential sum function e_n(x).
- New `calc.zeta2` computes the Riemann zeta function of two arguments.
- `calc.Psi` now accepts complex numbers.
- The release has been named after the the City of Covington, Louisiana.
New in Agena 3.1.3 (Jul 25, 2023)
- New `pytha4` computes x^2 - y^2 without undue underflow or overflow and treating subnormal numbers accordingly. The function also internally computes in 80-bit precision instead of 64-bit precision. Please note that all these features make the function slower than the naive `x**2 - y**2` approach.
- `erfc` has become 13 percent faster in the real domain, also benefitting `stats.cdfnormald`.
- Slight tweak to `bessely`.
- Improved accuracy of `math.hypot4` in the real domain.
- Auxiliary functions computing polynomials have been reduced to the absolute minimum, still providing all the speed benefits introduced with the last update.
- `hypot4` returned wrong results with arguments close to +/- infinity. This has been fixed.
- All undocumented mathematical reference functions have been moved from the `fastmath` package to the new `testlib` package. All duplicates have been removed.
New in Agena 3.1.2 (Jul 23, 2023)
- The factories produced by `calc.polygen`, for polynomials of degree 0 to 30, have been tuned by up to 135 percent. The larger the degree, the faster the factories have become.
- The following integral functions have been tuned: `calc.intde` has become 45 percent faster, `calc.intdei` 39 percent faster, and `calc.intdeo` 20 percent faster.
- `calc.fmings` has become five percent faster.
- Both `calc.sigmoid` and `calc.logistic` have been tuned by 13 percent.
- `stats.cdf` has been tuned by 40 percent.
- The following 80-bit floating-point operators have been tuned: `exp` by two percent, `ln` by seven percent, `gamma` by 17 percent.
- Significantly improved Chapters 10.1 Tables, 10.2 Sets, 10.3 Sequences and 10.4 Registers of the Primer and Reference.
- Improved the Quick Reference, tabs `Tables`, `Sequences` and `Registers`.
New in Agena 3.1.1 (Jul 20, 2023)
- The factories produced by `factory.pick` have been tuned quite a bit.
- Improved Chapters 10.1 Tables, 10.3 Sequences, 10.4 Registers and the index of the Primer and Reference.
New in Agena 3.1.0 (Jul 13, 2023)
- The new function `factory.anyof` creates a factory that when called tries each given function with the arguments passed to the factory. It also accepts structures that have a '__call' metamethod. Example:
- > isalphanumeric := factory.anyof(strings.isnumber, strings.islatin);
- > isalphanumeric('1'):
- true
- > isalphanumeric('i'):
- true
- > isalphanumeric('ü'):
- null
- The function has originally been conceived by Gary V. Vaughan, written in Lua, and has been ported to C for much better speed.
- New `factory.pick` picks only given results from a function call, by taking a function and the positions of the results to be returned and producing a factory that when called delivers the results of interest. Imagine a function g
- > g := proc() is return 10, 11, 12, 13, end;
- where we want to have only the first and third result of its call, that is numbers 10 and 12. We define
- > import factory;
- > f := factory.pick(g, 1, 3);
- > f():
- `curry` has been moved to the `factory` package. There is no alias for backward-compatibility. If you want to use it, initialise the `factory` package first:
- > import factory;
- > f := << x, y, z -> x*y + z >>;
- > t := factory.curry(f, 10); # returns f(10, y, z)
- The new function `tables.isarray` checks whether a table is a pure array, i.e. only contains one or more elements in the array part of the table but none in the hash part. Also determines whether there are holes in the array.
- The new function `tables.ishash` checks whether a table is a pure dictionary, i.e. only contains one or more elements in the hash part of the table but none in the array part.
- New `environ.callable` returns its argument if it is a function. If the argument is a structure and has a '__call' metamethod, returns this metamethod. The function is useful to first check whether a value can be successfully called like a function:
- > r := environ.callable(f) and f(...);
- The idea has been taken from Gary V. Vaughan's lyaml package, but translated into C.
- New `strings.sub` has been taken from Lua 5.4 and returns a substring with automatic correction of both the left and the right border if they are out-of-range. In the following example both borders are wrong but no error will be issued, returning the whole string instead:
- > strings.sub('agena', 0, 10):
- The new C API function `agnL_iscallable` checks whether a value is callable like a function.
- The new C API function `agn_isposint` checks for a positive integral number in the stack.
- The new C API function `agn_isnonnegintint` checks for a non-negative integral number in the stack.
- The new C API macro `lua_isfalseorfail` checks whether a value in the stack is either `false` or `fail`.
- The new C API macro `lua_isnilfalseorfail` checks whether a value in the stack is either `null`, `false` or `fail`.
- The 'json' package could not treat UTF-8 characters and JSON arrays. This has been fixed. Also did some minor tuning of both `json.encode` and `json.decode`.
- The release has been named after the the city of Conroe, Texas.
New in Agena 3.0.0 (Jul 4, 2023)
- The `is` token in procedure definitions with `proc` and `procedure` has become optional.
- The behaviour of substring indexing when using the `to` token has been changed: if the right border is greater than the length of the string, then it is auto-corrected to the string length, thus no longer issuing out-of-range errors. If the left border is 0 or greater than the length of the string, however, there will still be an error:
- > s := 'agena'
- > s[2 to 6]: # resulted in an error before
- gena
- > s[6 to 7]:
- Error in substring op: left index 6 out of range.
- Added the 'json' package which has originally been written by David Heiko Kolf for Lua 5.1+. It encodes a table to a string representing a JSON object and can also decode a JSON object represented by a string to an Agena table:
- > import json
- > data := [
- > 'city' ~ 'Tel Aviv',
- > 'iscapital' ~ false,
- > 'founded' ~ 1909,
- > 'details' ~ ['population' ~ 467875, 'area' ~ 52]
- > ]
- > s := json.encode(data):
- {"details":{"population":467875,"area":52},"iscapital":false,"city":"Tel Aviv","founded":1909}
- > json.decode(s):
- [city ~ Tel Aviv, details ~ [area ~ 52, population ~ 467875], founded ~ 1909, iscapital ~ false] 95
- For better portability of Lua code to Agena, added the Lua 5.4 function `strings.byte` which returns all the ASCII codes of the characters in a string. Examples:
- > strings.byte('agena'):
- > strings.byte('agena', 1, 5):
- 97 103 101 110 97
- New `os.mklink` creates symbolic or hard links on the file system.
- In OS/2, `os.fattrib` can now change file timestamps, at last.
- `stats.minmax`, when given a sequence, did not ignore `undefined` values as it should have. This has been fixed.
- Removed the following aliases to deprecated functions and constants:
- `strings.splitfields`, call `strings.fields` instead;
- `strings.wrapmissing`, call `strings.wrap` with the `true` option instead;
- `math.arctanh`, call `arctanh` instead.
- `environ.pathmax`, call `environ.kernel('pathmax')` instead;
- `environ.buffersize`, call `environ.kernel('buffersize')` instead;
- `environ.minlong`, call `environ.kernel('minlong')` instead;
- `environ.maxlong`, call `environ.kernel('maxlong')` instead;
- `environ.maxinteger`, call `environ.kernel('maxinteger')` instead.
- Removed various experimental, test and obsolete functions, all undocumented, from the `math`, `fastmath`, `strings`, `os`, `hashes`, `tables` and `sequences` packages.
- Cleansed the header files and UNIX build scripts. Also improved description on how to compile Agena in OS/2, in file src/makefile.os2.
- Besides a version number, each major Agena release will now have a codename. We are starting with the city of Tel Aviv, State of Israel.
New in Agena 2.41.3 (Jul 4, 2023)
- calc.chebyt` has become more than thrice as fast for arguments x with |x| <= 1. The results have become more accurate, as well. With arguments |x| > 1, the function now no longer computes cos(n*arccos(x)), but returns cosh(b*arccosh(x)) instead, even for x < -1.
- In OS/2 and DOS, the complex versions of `arcsin`, `arccos` and `arcsec` have been tuned.
- Although not present on the ZX Spectrum, the following functions are now available in the `zx` package, most of them implemented upon existing ZX CORDIC logic:
- The functions `zx.ASNH` for inverse hyperbolic sine, `zx.ACSH` for inverse hyperbolic cosine and `zx.ATNH` for inverse hyperbolic tangent have been added.
- New `zx.SINH` approximates the hyperbolic sine, `zx.COSH` the hyperbolic cosine, `zx.TANH` the hyperbolic tangent, `zx.SECH` the hyperbolic secant, `zx.CSCH` the hyperbolic cosecant and `zx.COTH` the hyperbolic cotangent. Also added secant, cosecant and cotangent functions `zx.SEC`, `zx.CSC` and `zx.COT`.
- The new function `zx.ERF` implements the error function and `zx.GAM` the Gamma function.
- The new constant `zx.E` represents Euler's constant zx.EXP(1) = 2.7182818...
- The constant `zx.PI` has been changed from Agena's Pi constant to 4*zx.ATN(1) which is much closer to the ZX Spectrum implementation.
- Improved the index of the Primer & Reference.
New in Agena 2.41.2 (Jul 1, 2023)
- `strings.format` and thus also `printf` support the new '%le' specifier, printing numbers in scientific notation with 16 fractional digits by default.
- With argument n, 255 < n < 512, `math.lnfact` has been tuned by seven percent, fetching the result from an extended look-up table.
- `math.zeroin` inadvertently returned the absolute value of its argument if it was not within the given epsilon range. This has been fixed and now the original argument is returned.
- The new function `long.lnfact` computes the logarithmic factorial ln n! in 80-bit precision.
- The new function `long.lnabs` implements the natural logarithm of the absolute value of its argument.
- New `long.redupi` subtracts the nearest integer multiple of Pi from its argument.
- Introduced the new constant `long.DoubleEps` which represents a 80-bit machine epsilon value, around 1.0842e-19.
- New constant `long.MinDouble` represents the smallest normalised positive longdouble value, around 3.3621e-4932.
- New `long.zeroin` "sets" its argument to zero if it is less than or equal to `long.DoubleEps`. You may additionally pass an alternative epsilon value.
- The new function `long.zerosubnormal` checks whether its longdouble argument is subnormal and in this case returns 0, otherwise returns its argument.
- New `long.normalise` converts a subnormal longdouble into the smallest normal longdouble value.
- The `long` pretty-printer has been improved by no longer outputting numbers with too many digits. If a value "absolutely" is less than 1e-20 or greater than 1e20, then it is formatted in scientific notation.
New in Agena 2.41.1 (Jun 27, 2023)
- New `stats.laplace` implements the Laplace distribution and the corresponding probability density function.
- New `long.gamma` computes the gamma function in 80-bit precision.
- The `lngamma` operator can now process longdoubles, and the new corresponding `long.xlngamma` function, too. Both compute the logarithmic gamma function in 80-bit precision.
- New `long.fact` returns the factorial n! in 80-bit precision.
- Processing of long doubles by the `exp` operator and by `long.xexp` has been tuned, same with the `^` exponentiation operator.
- With very big numbers, the `long` package pretty-printer `long.tostring` crashed Agena. This has been fixed.
New in Agena 2.41.0 (Jun 25, 2023)
- New `math.dblfact` computes the double factorial n!! and `math.trifact` the triple factorial n!!!.
- Previously undocumented `calc.lnfact`, which computes the logarithmic factorial, has been described in the Primer and Reference.
- New `calc.auxSiCi` implements auxiliary sine and cosine integrals.
- New `calc.Cin` computes the entire cosine integral.
- New `calc.Ein` implements the entire exponential integral.
- New `calc.eta` computes the Dirichlet Eta function.
- New `stats.logistic` computes both the logistic distribution and the corresponding probability density function.
- New `stats.geometric` computes the geometric cumulative (probability point) distribution, and alternatively the geometric probability point distribution.
- New `calc.logseries` computes the log(arithmic) series cumulative distribution.
- In the real domain, `beta` has become seven times faster.
- Integer exponentiation in the complex domain with the `**` operator has been tweaked with larger powers and with OS/2 and DOS in general.
- Tuned `proot` in the complex domain a little bit.
- Improved accuracy of `fma` and `squareadd` in both the real and complex domain, at the expense of speed.
- `astro.moonriseset`, `astro.sunriseset`, `fractals.lsin` and `fractals.lbea` have been tuned.
- `calc.euler` now computes in O(1) time instead of O(n) with argument n <= 186.
- In OS/2 and DOS, `arctan2` has been tweaked.
- In OS/2 and DOS, the complex versions of `arcsin`, `arccos`, `arcsec` and `arcsinh` have been completely rewritten, with the code much shorter than before. The speed of all four functions, however, remains the same.
New in Agena 2.40.1 (Jun 19, 2023)
- A `catch` statement in the code could cause Agena to crash every time the parser could not distinguish between a user given error variable and the start of the actual `catch` block. When an explicit error variable is given, then the `catch` token must now be followed by the `in` token:
- try
- error('my error')
- catch in errmsg then
- print(errmsg)
- end;
- The old syntax without an explicit error variable name still works as before:
- try
- error('my error')
- catch
- print(lasterror)
- end;
New in Agena 2.40.0 (Jun 18, 2023)
- `signum` accepts booleans: with `true` returns +1, and with `false` or `fail` returns -1. Like `abs`, this allows for conditional arithmetics without using `if`s.
- New `math.redupi` subtracts the nearest integer multiple of Pi from its argument.
- `exp2` has been tuned by 35 percent in the real domain. The speed in the complex domain remains the same.
- In the complex domain, the `log` operator has been tuned by a factor of 2.3.
- In the complex domain, `arcsech` has been tuned by a factor of 2.7. It has become 20 % faster in the real domain, too.
- In the complex domain, `arccsc` has been tuned by 15 percent, and by 12 percent in the real domain.
- In the complex domain, `arccsch` has been become twice as fast. In the real domain, its speed has been increased by 18 percent and the function has become more accurate around the pole.
- `arctanh` has become 15 percent faster in the real domain. The speed in the complex domain remains the same.
- `dual.arctanh` has been tweaked by 15 percent.
- The 'pathmax' and 'maxinteger' settings are now being returned when calling `environ.kernel` without arguments.
- Reduced memory consumption of `os.listcore` and `os.iterate` primarily on UNIX-based systems.
- The system variable `environ.pathmax` has been deprecated. Use environ.kernel('pathmax') instead.
- The system variable `environ.buffersize` has been deprecated. Use environ.kernel('buffersize') instead.
- The system variable `environ.minlong` has been deprecated. Use environ.kernel('minlong') instead.
- The system variable `environ.maxlong` has been deprecated. Use environ.kernel('maxlong') instead.
- The system variable `environ.maxinteger` has been deprecated. Use environ.kernel('maxinteger') instead.
- Aliases for all the above mentioned system variables have been provided to ensure backward-compatibility.
- `math.arctanh` has been deprecated. Use `arctanh` instead. An alias has been provided to ensure backward-compatibility.
- Alias `math.modinv` has been removed. Use `math.invmod` instead.
- Alias `strings.isabbrev` has been removed. Use `strings.isstarting` instead.
- Alias `math.hEps` has been removed. Use `hEps` instead.
- Alias `rtable.rdelete` has been removed. Use `rtable.purge` instead.
- Alias `rtable.rget` has been removed. Use `rtable.get` instead.
- Alias `rtable.rinit` has been removed. Use `rtable.init` instead.
- Alias `rtable.rmode` has been removed. Use `rtable.mode` instead.
- Alias `rtable.rset` has been removed. Use `rtable.put` instead.
- Alias `math.arcsinh` has been removed. Use `arcsinh` instead.
- Alias `math.arccosh` has been removed. Use `arccosh` instead.
- Alias `math.exp2` has been removed. Use `exp2` instead.
- Alias `math.exp10` has been removed. Use `exp10` instead.
- Alias `sadd` has been removed. Use `sumup` instead.
- Alias `smul` has been removed. Use `mulup` instead.
- Alias `qsadd` has been removed. Use `qsumup` instead.
- Alias `tables.swap` has been removed. Use `swap` instead.
- Alias `sequences.swap` has been removed. Use `swap` instead.
- Alias `registers.swap` has been removed. Use `swap` instead.
- Alias `os.iseCS` has been removed. Use `os.isos2` instead.
- Alias `os.mkstemp` has been removed. Use `io.mkstemp` instead.
- Alias `os.isUNIX` has been removed. Use `os.isunix` instead.
- Alias `os.isANSI` has been removed. Use `os.isansi` instead.
- Alias `os.mousebuttons` has been removed. Use `os.mouse().mousebuttons` instead.
- Alias `math.Phi` has been removed. Use `Phi` instead.
- Cleansed the source file distribution.
New in Agena 2.39.12 (Jun 12, 2023)
- New `os.isdriveletter` checks whether its input string represents a drive letter, such as `c:` or `d:`.
- New `os.isdow` returns `true` in DOS, OS/2 and Windows, and `false` otherwise.
- New `os.getdirpathsep` returns both the directory and path separators. Examples are '' and ';' in DOS-based systems.
- `os.getmodulefilename` now supports OS/2.
- `strings.tolower`, `strings.toupper`, `strings.isolower` and `strings.isoupper` now work with strings that include embedded zeros, which are preserved in the output.
- The following functions now ignore embedded zeros and check the entire string: `strings.isupperlatin`, `strings.islowerlatin`, `strings.isloweralpha`, `strings.isupperalpha`, `strings.ismagic`, `strings.islatin`, `strings.islatinnumeric`, `strings.isnumber`, `strings.isspace`, `strings.isalpha`, `strings.isalphaspace`, `strings.isalphanumeric`, `strings.isascii`, `strings.words`.
- Tweaked `os.listcore` and `os.iterate` by avoiding internal string duplication.
- Tuned `strings.capitalise` and `strings.uncapitalise` by 13 percent.
- The internal character buffer library contained a flaw that could crash Agena, especially with larger strings. This has been fixed. The operators and functions affected were: `join`, `replace`, `bytes.pack`, `com.read`, `strings.remove`, `memfile.charbuf`, `memfile.bytebuf`, `memfile.bitfield`, `memfile.dump` and `memfile.replicate`.
- `bytes.trailzeros` now correctly fills trailing zeros with 1's in the second return.
New in Agena 2.39.11 (Jun 7, 2023)
- `os.isvaliddrive` now supports OS/2 and DOS.
- `os.isremovable` now also works in DOS.
- In OS/2, `os.drivestat` now returns FSD Attach Data - if it is available - with the new 'rgFSAData' field. The numeric values represented by the 'iType' field have been explained in the Primer and Reference. The function now accepts alphabetical drive letters only - previously, '[' and '@' were erroneously taken in OS/2, as well.
- In OS/2, DOS and Windows, the drive letter may be given as a single character (e.g. 'c'), a letter followed by a colon ('c:') or a letter followed by a colon and a (back)slash ('c:/', 'c:\') to the following functions: `os.drivestat`, `os.ismounted`, `os.isremovable` and `os.isvaliddrive`.
- `strings.strlen` no longer inadvertently returns four values.
- Various cross-references have been added to Chapter 9 `Strings` of the Primer and Reference.
New in Agena 2.39.10 (May 31, 2023)
- `strings.isending`, `strings.chomp`, `strings.ltrim`, `strings.rtrim` and `strings.lrtrim` could modify their input strings. This security issue has been fixed.
- `strings.rtrim` and `strings.lrtrim` could return a garbled string, causing memory leaks, if the second argument consisted of more than one character. This has been fixed.
- `strings.rotateleft` and `strings.rotateright` could theoretically cause memory leaks. A patch has prophylactically been applied.
- In Windows, `os.symlink` modified its input strings and could even crash Agena. This has been fixed.
- The error messages of `strings.isending`, `strings.ltrim` and `strings.rtrim` have been fixed.
New in Agena 2.39.9 (May 29, 2023)
- In Windows, `os.iterate` did not properly clean up internal directory handles. This has been fixed
- os.iterate` now conducts an automatic garbage collection before returning the result, so that all open directory handles are closed and directories traversed before can be changed
- os.iterate` did not work in Windows 2000. This has been fixed
- In Windows, `os.realpath` on failure just returned its first argument. Now it returns `fail` as on all other platforms
- In OS/2, DOS and Windows, `os.realpath` no longer returns the current working directory when given just the drive (such as `c:` or `c:`), but now just returns the drive letter, followed by a colon and a slash
New in Agena 2.39.8 (May 29, 2023)
- os.iterate` has been patched to properly iterate an entire Windows drive. It also automatically skips Windows system directories instead of issuing an error. Examples for system directories are `PerfLogs` or `AppData`
- The new function `os.issysdir` checks whether a Windows folder is a system directory
- os.fstat` can now properly detect all kinds of Windows system directories and sets the 'system' entry to `true` instead of `false`
- When only a drive letter along with a colon is passed to `os.dirname`, then the function appends a trailing slash to the result, e.g. 'c:' -> 'c:/'
- os.whereis` has become around 25 percent faster while using much less memory than the previous version did
- strings.glob` modified the input strings. This has been fixed
New in Agena 2.39.7 (May 24, 2023)
- The factory created by `os.iterate` no longer returns the '.' and '..' placeholders depicting the current and parent directories.
- `os.dirname` - when given a path to an actual directory on the file system - returned a string with a trailing embedded zero ('