Documentation * FAQ * Download * Frink Applet * Web Interface * Sample Programs * Frink Server Pages * Donate
Frink changes almost every day. If your version of Frink is more than a few days old, you're probably out of date! (That doesn't mean that old programs will be invalidated, but that new, useful features and optimizations are added all the time.) If you'd like to be notified of major new releases via e-mail, please subscribe to the "Frink Language" project at freshmeat.net. (Link opens in new window.)
showDimensionName[bool] function which
switches display of the names of dimensions on and off. For example, when
you enter "1 K", the result is displayed as 1 K
(temperature). Setting this flag to false suppresses
the "(temperature)" display. For more information, see the Setting Number Formats section
of the documentation.
frink.parser.Frink.getVariableAsDouble(String variable, String units)units to be either null or
the empty string. This tries to return the value of the variable as a
dimensionless number. And it must be a dimensionless number or an
exception will be thrown. See the documentation on Frink's integration methods for more
information. Thanks to Alberto Di Lullo for the suggestions.
secantAzimuth function to calculate the time that
a planet will pass through a given azimuth as seen from a location on
earth.
list = newJava["java.util.ArrayList", [] ]
ulist = callJava["java.util.Collections", "unmodifiableList", list]
ulist.size[]
This problem occurs because ulist is an instance of the
inner class
java.util.Collections$UnmodifiableRandomAccessList in which,
for some reason, the class has no access specifier and is thus "package
private" which, due to the aforementioned bug in Java's handling of
method invocation, is considered not accessible (even though the
message is public) when using reflection, but would be perfectly fine to
call from compiled code. Sigh. There may be a nasty workaround to try
and call this method via an interface specification, but I'm not sure.
For more information, see the discussion in the entry for 2007-06-28. I already implemented some nasty
workarounds to try and fix part of these bugs.
Thanks to Rowan Worth for the bug report.
100 m -> "ft"
and returned undef in these situations. The excessive
security check has been modified. Thanks to André Sihera for the
report.
deepCopy[x] function to perform a recursive
deep copy of all the parts of a container class. The function can be
called with any expression type. The function currently deep copies
everything contained in arrays, dictionaries, and sets, and all of the sets
contained within them. It is thus useful for copying nested data
structures, multi-dimensional arrays (which are arrays of arrays, etc.) and
prevents modification of the original or the copy from changing the other.
It does not currently deep copy Java objects, Java arrays, nor
objects created from a class specification, although it may do some of
these in the future.
symbolicMode[true]
f[x] := sin[x] + 4
f[y^2]
4 + sin[y^2]
\u0966-\u096f.
९८७६५४३२१०
9876543210
approxLog2[0].
10.0^32000.5
sqrt[n,digits] in root.frink. This now
uses adaptive working precision and smart initial guesses to produce
results more rapidly.
6_0). Thanks to Neal Crook for the bug
report.
feed_face\\16
0xfeed_face
0b0001_0101_0000
Thanks to Neal Crook for the suggestion.
FrinkVersion[] function to return the current
version of Frink from within a program. (You can also find out the
current version from the command-line by running:
frink -v
or
frink --version
binomial[m,n] to calculate
binomial coefficients. This is of the number of ways m things
can be chosen n at a time, with order being
unimportant. This is sometimes called "m choose n" or "m C n". This is
equivalent to m!/(n!*(m-n)!) although calculating that way often leads to
way-too-big numbers. For example, binomial[10000, 9998] is equal to
49995000, but if you calculated it naively, you'd have to calculate
10000! which is a 35660-digit number, and divide it by another huge
number, which could be inefficient and slow.
->
operator, Frink will now make more suggestions for factors to multiply or
divide by. Notably, it will look for squares and square roots of existing
units and suggest those as well. For example:
(8 pi 1 erg/cm^3)^(1/2) -> gauss
Conformance error
Left side is: 1.5853309190424043 m^(-1/2) s^-1 kg^(1/2) (unknown unit type)
Right side is: 1/10000 (exactly 1.0e-4) s^-2 kg A^-1 (magnetic_flux_density)
Suggestion: multiply left side by permeability^(1/2)
For help, type: units[permeability]
to list known units with these dimensions.
Thanks to Anne Archibald for the suggestion.
watt
1 m^2 s^-3 kg (power)
watt^(1/2)
1 m s^(-3/2) kg^(1/2) (unknown unit type)
The exponents of base dimensions can now be either integers or rational numbers. (Previously, only integers were allowed.)
This change was necessary to support some systems of units such as the
Gaussian and Heaviside-Lorentz systems of units, which build on the
"cgs" (centimeter-gram-second) system of units, but have very different
definitions of electromagnetic quantities than the International System
of Units (SI). For example, in the Gaussian system, electric current has
dimensions of cm^(3/2) g^(1/2) s^-2, and working
natively with this system requires fractional exponents.
While it does not usually make sense to have fractional exponents in
many systems of measurement nor in physical measurements, it is sometimes
necessary in some fields, quantum physics being another example. I have
also seen the use of fractional exponents in physical equations, such as
the square root of volumetric flow ( m^(3/2) s^(-1/2) ).
In the future, enabling fractional exponents may require a flag, but it may not. The reason for having a flag would be to detect certain types of errors as early as possible.
Thanks to Anne Archibald for a very edifying discussion of the needs of handling Gaussian units properly.
a/b where the numerator a was a large integer
(magnitude greater than 231). This did not happen in the cases
where the values of the expressions could be immediately evaluated at
compile time, but happened when more complex expressions involving
uncommon operators or functions were encountered, like
2^40 / 40!.
The error manifested itself by printing
NotAnIntegerException and halting the program. This bug did
not cause silent errors, nor did it ever produce incorrect
answers; if you encountered it, the program halted with this error
message.
Also note that multi-line mode requires that you click the "Go" button to execute the statement. Hitting the return key just moves the cursor to a new line.
array.pushFirst[x] and
array.popFirst[] methods to allow pushing and popping
from the front of an array.
== or !=
operators. Previously, this would return an error. Comparing complex
numbers using other relational operators, such as <, will
still return an error, as the complex numbers are not a well-ordered field.
EulerMascheroniConstant to the standard data file.
array.lexicographicPermute[]
to produce all the permutations of the elements in the array in
lexicographical order. This is in contrast to the
array.permute[] method which returns the permutations
in no particular order (and does thus not require them to be comparable.)
update method in
FrinkCanvas.
sunApparentRA and
sunApparentDecl into a single
sunApparentRADecl function.
xxxSiderealTime to the more accurate
xxxSiderealAngle.
apparentLocalSiderealTime function which was
completely broken in two different ways.
hourAngle function to calculate the hour angle of
an object.
parallacticAngle function to calculate the
parallactic angle of an object.
moonPositionAngle and
moonPositionAngleRelativeToZenith functions that calculate
the position angle of the moon's bright limb relative to the North Point
of the moon and the zenith respectively.
paint methods in the guitoolstest.frink file.
metretes and fixed the
definition of oldhollandcable (from a prefix to a unit
definition) in the standard data file.
Thanks to John G. Malecki for spotting these problems.
sum[x]
function to add the elements of a list or an enumerating expression.
this member variable to objects created from
classes. This was necessary to be able to pass the current object as a
parameter to functions.
EnglishToChinese, Chinese, FromChinese to imply
simplified Chinese instead of traditional Chinese. This probably
reflects modern practice more closely. Traditional Chinese will likely
not work.
charList[str] to return a list of characters
in a string.
isInteger[num] function which returns true if
a number is a dimensionless integer, false otherwise.
It now supports calculation of the following at different altitudes:
6.3 hour -> [0, "weeks", "day1", "hours", "minutes"]
This is still an error, but now it produces a more helpful error message. Thanks to Eric Hill for the bug report.
eval[] and unsafeEval[] are passed an
array, all elements of the array will now be evaluated and the
result will be returned in an array. This greatly simplifies things like
reading from a file and turning strings into numbers.
newJavaArray[classname, length] method to allow
creation of arrays of Java objects or Java primitives. See the Creating Java Objects section
of the documentation.
collapseIntervals[bool]
function to control the collapse of degenerate intervals (those with the
same upper and lower bound) into a single real number.
As an important note, this fixes the case where you couldn't create an external process through introspection, for example:
runtime = callJava["java.lang.Runtime", "getRuntime", []]
process = runtime.exec["ls"]
println[process.available[]]
The above wouldn't work in the past because the process
object wasn't usually an instance of java.lang.Process, but
of a subclass like UNIXProcess (on Linux) or
ProcessImpl (on Windows), and the aforementioned Sun bug
caused failure when trying to invoke methods on these classes, which were
declared private, even though the methods were public and
the calls would work fine in normal Java code. So now you can really
call external processes from Frink, if you want.
chars[x]
function to return an array of Unicode character codes even when passed a
single-character string.
partitionCount[n] to return the number of
ways that the positive integer n can be partitioned.
for, do...while, and
while loops. This allows for cleaner breaking out of nested
loops. See the Loops section of the
documentation for examples.
length[set] function return a value much
more efficiently for sets.
Warning: This release fixes a significant bug that was introduced recently.
Fixed a major bug that was introduced recently when multiplying by zero. I had added an over-eager optimization that turned this case into 0 (without dimensions) at compile-time, which worked for many cases, but this broke dimensional analysis. For example, the case below would produce a conformance error:
4 s + 0 s
If that produces an error, make sure you update your version of Frink!
It should, of course, produce 4 s (time).
You would also see the loss of units in something like:
0 s
If this produces 0, and not 0 s (time), then you should
update.
Many thanks to Jared Updike for informing me of the bug.
sin[x] when x is an undefined variable will
immediately halt with an error. (If you've set
symbolicMode[true] then this will return the unevaluated
expression sin[x] and will not generate a warning.)
"Fail-fast" behavior prevents traditional programs from running along merrily and building (potentially huge) symbolic expressions if you forgot to define a variable. For most programs, you'll want to know immediately if you forgot to define a variable's value. This behavior had been altered with this month's symbolic algebra changes.
JDE[day] function to take a
dimensionless value (the JDE value in days) and create a date object from
it:
JDE[2451545.0]
AD 2000-01-01 04:58:56.170 AM (Sat) Mountain Standard Time
x+0 to
0.
x^x.
symbolicMode[bool] flag to suppress a variety
of warnings that are normally presented to the user when running in
ordinary programming mode. When set to true, warnings for
undefined symbols and functions are suppressed.
frink.gui.FrinkStarter class that allows
selection of starting in command-line mode (with no arguments) in AWT GUI
mode (with --gui or --awt or -open
filename command-line arguments), or in Swing GUI mode (with
--swing command-line argument.)
sin[x] to not always throw
fatal exceptions when passed arguments that can't immediately be
evaluated. If these functions cannot evaluate their arguments, they check
to see if any of the arguments contain undefined symbols, and, if so,
return the original expression quietly. If the arguments are of the wrong
type entirely, they will still throw an exception. This is an attempt to
allow symbolic manipulation of these functions, while trying to preserve
some "fail-fast" behavior for ordinary programs. In the future, this
behavior may be further altered by a "symbolic mode" flag.
D[_f[_u], _x] <-> D[_u, _x] D[_f[_u], _u]
rationalAsFloat[true] function to force
display of rational numbers as floating-point. Setting this to
true will display all rational numbers as floating-point
approximations. They will continue to be represented internally as
floating-point numbers for accuracy. For more information, see the Setting Number Formats section
of the documentation. Thanks to Robert Munafo for the suggestion, as well
as several good suggestions for improving the documentation.
rationalAsFloat, showApproximations, setPrecision) in a
restricted context. This prevents, say, users of the web
interface from messing up the display settings for all users. Note that
someday these flags might be on a per-interpreter basis, but that'll be
significantly slower.
setPrecision[digits]
function, which allows the user to set the number of digits of precision in
floating-point calculations. I kept this function as somewhat of a
secret due to the possibility listed above. For more information, see the
Setting Precision section
of the documentation.
transformExpression[expr] function
pre-evaluate its arguments like most normal functions.
The new frink.jar file can now be compiled to a stand-alone executable using the experimental gcj 4.3 eclipse-merge-branch. (Unfortunately, it's compiled without optimization, because that pegs the CPU for over 72 minutes, and then blows out my system after trying to use over a gigabyte of virtual memory. Anyone want to donate me a new computer with tons of memory? Or try compiling it with -O3?) Thanks to Reuben Thomas for the suggestions and error reports.
Hint: If you install the gcj package linked above, the command line to compile with full optimization will be something like:
gcj -O3 --main=frink.parser.Frink -o frinkx.exe frink.jar
Note: Yes, the executable has been stripped to reduce its size (original was about 48 MB.) I may further compress it with an executable packer which will reduce the size to less than 5 MB at the cost of slightly slower startup time.
showUndefinedSymbols[false]
_x + _x <-> 2 _x
The <-> operator seperates the two sides of a
transformation rule.
The above implements the usual mathematical equivalence x+x=2x. A
variable preceded with an underscore like _x is a pattern
that matches any expression. (If you just have a variable
called, say, x in a rule, it will match only the literal
symbol x.) The fact that the above expression has
_x in two places on the left-hand side enforces that the
same pattern has to be the same on both sides of the addition
operator.
All defined patterns can then be applied by the
transformExpression[expr] function:
transformExpression[y+y]
2 y
Note that it also works with arbitrary expressions on either side:
transformExpression[2x + 2x]
4 x
You can define more transformation rules, and they will all be applied. Below are a couple of the most common transformation rules:
0 _x <-> 0
1 _x <-> _x
0 + _x <-> _x
_x * _x <-> _x^2
_a _x + _b _x <-> (_a+_b) _x
_x^_a * _x^_b <-> _x^(_a+_b)
If you play with this a bit, you'll see that the structure of the expression is matched, and the structure has to match exactly.
More work needs to be done with matching all orderings of addition and multiplication operators, which are commutative, and the syntax may change, but this is a huge, huge step forward for Frink!
Homework: Using the above examples, define transformation rules
to take the derivatives of expressions, like: D[sin[2x],x]
You can do it for many types of expressions, but not all.
frink.jar file and added
some apparently-unused inner classes that were preventing compilation with
some picky tools like gcj. These missing classes may have also prevented
execution on some odd JVMs, at least in theory. Thanks to Reuben Thomas
for the information.
The exact workings of this may change, but you can now specify arbitrary
patterns beginning with the underscore character _ and with
an optional name. For example, to transform instances of x +
x (where x is any pattern) into 2x, you
can try the following code:
substituteExpression[x+x, _y + _y, 2 _y]
2 x
The pattern _y + _y matches any pattern where both
sides of the + operator are the same pattern, and replaces
that pattern in the first expression x+x with 2
x.
Or, more generally, to handle sums of products of similar variables:
substituteExpression[3x+4x, _z _y + _x _y, (_z+_x)_y]
7 x
Using the same rule:
substituteExpression[(z-3) x+4x, _z _y + _x _y, _y (_z+_x)]
x (1 + z)
That may seem simple, but it's an amazingly powerful feature that will allow arbitrary mathematical transformations. More information and features to come, and more easy specification of transformation rules to come.
+ operator to also allow string concatenation gets in the way
of doing this universally. Sigh. I need to choose a different string
concatenation operator. I knew I'd regret that choice.
parseInt[str, base] to
parse a string into an integer, treating the string as being in the
specified base. This is faster, but less flexible, and more sensitive,
than using something like eval[str\\16] for the same
purpose.
arccosh[x]
or acosh[x]. This function works for complex and
interval arguments.
set datatype useful. You can now construct sets,
add elements to a set (using the put method), test for
containment, and more. For more information, see the Sets section of the documentation.
showUndefinedSymbols[bool] to
control whether or not "(undefined symbol)" should be shown after all
undefined symbols. This would be annoying in symbolic calculations. This
function may change.
approxLog2[x] function to return a double
and return a much better initial estimate for integers. This will help
the initial estimate in many numeric algorithms.
collapseIntervals[bool] function to indicate
whether or not degenerate intervals (that is, those with equivalent lower
and upper bounds) should be collapsed into a single real number. The
default is false. This feature is still somewhat
experimental, but it should allow you to see what may happen with
different rounding directions in interval arithmetic, and see how
numerical error propagates as a result of different rounding directions.
substituteExpression[orig, from,
to] function to allow substitution of parts of an
expression with other expressions. This is part of the upcoming symbolic
mathematical capabilities. The name and behavior of this function may
change.
+ ) in several ways:
Note that the following changes may affect existing programs! It's very doubtful that anyone expects or codes for the old behaviors, but these changes could affect some oddly-written programs.
Slightly altered the semantics so that two units (i.e. numbers) which are added together in the midst of a string concatenation will get added first before the string is concatenated. This altered/fixed the case where string concatenation was always done first. For example:
s = 1
println["Next=" + s + 1]
now outputs Next=2 instead of the old behavior, which was
to print Next=11. (See how the promotion to string and
then string concatenation was done first.)
If you want the old behavior, you can get it by coercing one of the units to a string explicitly using the string interpolation rules. Either of the following works to give the old, weird behavior:
println["Next=$s" + 1]
println["Next=" + "$s" + 1]
date = now[]
offset = 1 year
println["1 year from now is about: " + date + offset]
1 year from now is about: AD 2008-04-11 10:07:45.100 AM (Fri) Mountain Daylight Time
The previous behavior was to do a string concatenation of the date and time, without separators, which is probably never what anyone wanted. And yes, it may have been best to have a completely different string concatenation operator in the first place.
expressionContains[a,b] and
freeOf[a,b] functions to support
symbolic calculations. These functions determine if the expression
a either contains or is free of expression b. The names and
behaviors of these functions may change.
gcd function if one of the
arguments was zero.
?rich
[metrichorsepower, electrichorsepower, Richter[n]]
??rich
[metrichorsepower = 588399/800 (exactly 735.49875)
m^2 s^-3 kg (power),
electrichorsepower = 746 m^2 s^-3 kg (power),
Richter[n]]
Note that this now displays the Richter[n] function which
converts energy values to/from their equivalent on the Richter scale.
This facility will make interactive calculations more friendly, and somewhat reduce the need to go to the documentation to find information about functions. This will also reveal some functionality that you may not have known about, such as the Richter function which must be implemented as a function because it's not linear.
Note that user-defined functions display their proper named arguments,
while built-in functions may display something like arg1.
This may change, or it may not, as Frink checks to see if a function has
named arguments and performs several optimizations if there are no named
arguments.
numerator[num] and
denominator[num] functions to return the numerator and
denominator of a rational number (or any number).
left[str,len] and
right[str,len] convenience functions to give
the left or right side of a string.
childCount[expr] and
child[expr, index] functions to support
symbolic calculations. These functions give information about the
structure of an expression and any child expressions. The names and
behaviors of these functions may change.
indexOf[string, substring] function to
find the first index of a given substring within a string. This returns
-1 if the substring is not found.
dict.clear[] to clear the contents of a dictionary.
length[dict] function return a value much
more efficiently for dictionaries.
earth...) from the sun.frink astronomical
library to its own new file, navigation.frink.
If you have programs written to use the above functions, they may require modifications:
East and West defined at the top of
the sun.frink file, changing your use
statement to instead include navigation.frink will
automatically give you the proper sign convention. Otherwise, you will
need to verify that your sign convention uses negative numbers for west
longitudes and positive for east.
Note: The sun.frink sign convention was chosen to
match the one that is widely used in all astronomical
calculations, by the International Astronomical Union, etc. It would
be nice to rewrite all the astronomical algorithms to follow the same
sign convention as geodetics, but that's really fraught with peril.
Sigh.
earthBearing and resultantLatLong) used
spheroidal calculations which would cause small errors and asymmetries
between the forward and reverse calculations. The calculations are now
symmetrical. These functions have replaced the old functions of the
same name, with the old functions being renamed to
lowAccuracy... You should be able to use the updated
functions without modification, as long as you note the sign convention
change.
Even the previous ellipsoidal calculation in the function
earthDistance has been replaced with the new algorithm.
The new algorithm will be more accurate as it uses an iterative
procedure to reduce error on the ellipsoid (most calculations on an
ellipsoid cannot be expressed in a closed form.) Currently,
convergence limit is set at 1 microdegree, which corresponds to about
.1 mm on the earth's surface. The previous calculations could have a
relative error on the order of earth's flattening squared.
earthDistanceAndBearing which returns a list
containing [distance, initBearing, finalBearing] as the
calculations for distance and bearing would repeat many of the same
calculations. If you're calculating both distance and bearing, this
function will be more efficient than calling earthDistance
and earthBearing.
update tag to the JNLP specification files
(used for Java Web Start and available only in Java 6) as it caused
problems in Java 1.5 and before (it said that the file was missing a
<jnlp> tag when it wasn't.) Thanks to the lovely Tara Stewart for
the bug report.
Added a couple of sample scripts to run Frink in command-line mode. You will need to edit them to match the paths on your system!
There is more information on startup options in the Running Frink section of the documentation.
update tag to the JNLP specification files
(used for Java Web Start and available only in Java 6) to tell Frink to
check for updates in the background while launching and then automatically
update if there's a newer version. I'm not sure how well this works, so
let me know if you have problems with Java Web Start.
set data type.
new dict
for new array. The syntax for accessing elements of an array
and of a dictionary is otherwise identical:
a = new dict
b@0 = 123
b@100 = 301
showApproximations[bool] function
which switches display of floating-point approximations for rational
numbers on and off. For more information, see the Setting Number Formats section
of the documentation.
gcd algorithm, as it was tested to be
faster than the new algorithm for larger numbers, especially on some
platforms.
i^4 is now exactly 1.
factor function for the first time.
break statement to break out of the
currently-executing loop. This applies to for,
do, and while loops. Labeled breaks may come
later.
gcd function to be about 10% faster.
This will improve the speed of Frink's gcd function and
improve performance when reducing rational numbers to simplest terms.
messageDigest[str,
algorithm] to calculate a variety of cryptographic hashes of
various strings. The algorithm parameter is a string
containing one of any hashing algorithms your Java platform supports, which
probably includes: "MD2", "MD5", "SHA-1", "SHA-256", "SHA-384",
"SHA-512". See the Cryptographic Functions
sections of the documentation for code samples.
modDiv[n,m,
modulus] to perform the integer modular division
n/m mod modulus which returns the integer result
if one exists, otherwise returns undef.
modInverse[n,modulus] to
find the integer modular inverse of n to the base
modulus and returns the integer result if it is invertible,
otherwise returns undef.
array.permute[]
to produce all the permutations of the elements in the array.
Warning: Older versions of Java may contain incorrect daylight saving time conversion for the U.S. in 2007 and beyond. Read below for more details.
If you use Frink to perform calculations with dates in the future, especially dates in the U.S.A., I would like to strongly urge you to make sure that your version of Java is updated to match U.S. daylight saving time changes. These changes were signed into law as part of the Energy Policy Act of 2005 and will take effect in 2007.
In short, "Clocks will be set ahead one hour on the second Sunday of March instead of the current first Sunday of April. Clocks will be set back one hour on the first Sunday in November, rather than the last Sunday of October."
Sun claims that this change has been made to the following Sun Java releases:
However, at the time of this writing, the latter three are apparently unavailable for download from Sun's web site.
In practice, I have apparently seen this change to be made in some earlier versions of the 1.5 branch, but they would probably know better than I would if the problem was only half-fixed in earlier releases. Updating is recommended.
There is also a (beta) timezone updater tool if you're not allowed to update to any of these VMs.
Failure to update your VM may cause significant errors in converting to or from any U.S. timezones. No changes to your Frink jar files or Frink programs will be necessary when your Java environment is up to date.
Note that Java 6 (also known as 1.6) has very recently been released and is available for download.
If anyone notices any unexpected changes in any Frink behavior under Java 6, please let me know!
randomGaussian[mean, sd] to return a
normally-distributed (i.e. "bell curve") random floating-point value with
the specified mean and standard deviation.
randomFloat[lower, upper] to return a
uniformly-distributed random floating-point value in the specifed range.
array.shallowCopy[]
to perform a shallow copy of the elements of an array. Arrays are normally
passed by reference, and this allows them to be copied easily and
efficiently.
Important Fix: Fixed a problem in the makefile introduced when checking in yesterday's changes. This may have caused certain files not to be packaged correctly and could have broken Frink entirely. Please download Frink again if you experienced problems with yesterday's build.
Turkey_Lira to Turkey_New_Turkish_Lira.
The symbols changed are:
| Country | Old Symbol | New Symbol |
|---|---|---|
| Azerbaijan | AZM | AZN |
| Mozambique | MZM | MZN |
| Romania | ROL | RON |
| Turkey | TRL | TRY |
earthradius_equatorial,
earthradius_polar, and earth_flattening in the
standard data file to use the WGS84 datum, which is most commonly used in
modern maps.
eval[string] more robust in the face of errors
thrown from low levels of Java, such as divide by zero errors.
Now, any Throwable is caught and the function returns undef
when an exception is caught.
java.vm.name.
If the VM did not have a property with this name, initialization of the
base converter class would fail and Frink would not display larger numbers
(absolute value 231 or larger) properly. This was a problem in
some Java 1.1 environments, notably on Nokia handhelds. Be sure that when
you install Frink on these environments, it says version 3.4 or 3.04 or
later. Thanks to Francis for the bug report!
return statement
was the last statement in the function. This is now much faster. It
improves the speed of calling such functions from 3% up to 700%.
sin[x]. This
gives a small speedup and a reduction in runtime memory usage.
arccsch[x] or
acsch[x], defined as ln[sqrt[1 + 1/x^2] + 1/x].
This function works for complex and interval arguments.
format function was not an integer.
arcsinh[x]
or asinh[x]. This function works for complex and
interval arguments.
use statements to look for files in an
internal library shipped within the jar file. (In directory
/lib/). This library is currently empty, but this paves the
way for a distribution of Frink with a larger standard library of code
implemented in Frink.
array.removeValue[value] now returns
true if the value is found and removed, and
false if no matching item was found. See the
Array Methods section of the
documentation for more.
futureboy.homeip.net to
futureboy.us. It appears that this may make pre-existing
Java Web Start icons ask you if you want to make file associations or
create icons. If you answer "yes," it looks like it won't bother you
again.
File |
Interrupt Calculation menu item.
It's possible that this causes problems on platforms with minimal Java support and no support for threading. If this is the case, please let me know.
version tag of Java Web Start
JNLP files to hopefully work around bugs in Sun's implementations where
the latest installed version of Java is not used. See below on how to fix
this manually.
Note that when Frink first starts up as a widget, it might appear to hang. This is because Sun's Java installation pops up a dialog box behind other windows that asks you if you want to trust the Frink applet. You may have to hunt for this window. You can choose to "always trust" the application so you don't have this problem repeatedly. This was supposedly fixed in Java 1.5, but it still seems flaky.
I should note that installing Frink via Java Web Start (outlined here) is still in all ways a better way to install Frink than via a widget. It's resizable, automatically updates itself when Frink changes, and more. But the kids these days seem to like these widgety dealies.
Many thanks to the lovely Tara Stewart and the lovely Adam Singer for showing me how a Mac works, updating their Java settings, letting me screw with their computers, helping me test this stuff, and making dinner while I screwed around.
deltaT[now[]] returns 65.184 seconds,
due to the leap second introduced at the end of 2005. (Frink planned for
this change in the 2005-08-30 release.) Be sure to set your clocks back
one second!
The current value of delta-T, the difference between Terrestrial Dynamical Time and UTC is now 65.184 seconds. Astronomers take note.
deltaT[now[]]
65.184 s (time)
-v or
--version command-line flag actually works. Thanks to Bill
Poser for the bug report.
-v or --version command-line flag to
print out the Frink version and exit. The format of this version string
may change in the future.
BigInteger.ONE
from the new factoring code. This yet again fixes some
incompatibility problems with some Java 1.1 distributions. I
didn't realize that these variables weren't required to be public until
Java 1.2, and all of the Java distributions that I'd tested with made them
public, even on PersonalJava 1.1. But not on the Sharp Zaurus.
The choice of using pack200 compression should be automatic and transparent. Note that pack200 compression is only chosen if you're using Java 1.5 or later. If you're using something older, downloads should still work as before.
The advantage of using pack200 compression is that the size of the file you have to download is reduced from 615 kB to 220 kB. This should happen automatically the next time you launch Frink from your Java Web Start icon.
If you haven't used Java Web Start to install and automatically update Frink, you can do so here.
The pack200 compression scheme is a little screwy, and requires repacking the original jar file. This may cause issues on some platforms that I haven't detected. If you have any problems with downloading Frink or running Frink on any platform, or if you get verification errors, please let me know as soon as possible.
(1/4)^(1/2) :
(-27)^(1/3) now
returns the real number -3.0 instead of the complex number
(1.5 + 2.598076 i) that it returned
previously. Both of these are valid cube roots, (all numbers can be
said to have three cube roots, at least 2 of which are complex,) but now
the "principal" real cube root is returned for real negative bases.
Please note that if an inexact floating-point number is substituted for
the exponent (e.g. (-27)^.333333333), this will
(correctly) return a complex number if the base is negative. This
means that exponentiation may be somewhat "discontinuous" in the
complex plane for negative bases (you're actually picking a different
root at nearby points,) so if continuity matters to you, you might need
to either make conscious adjustment of the root you desire, or just
force the exponent to be a floating-point number before exponentiation.
(Say, by multiplying by 1.0.)
(1/4)^(1/2) now returns
the exact rational 1/2, instead of 0.5.
Currently, this is only true for exponents with denominators of 2, which
will hopefully be improved when I add routines to find exact integer
roots, if such exist, for roots other than 2.
isPrime[x] to automatically use a faster
Lucas-Lehmer test if x is of the form 2n-1 (i.e.
Mersenne numbers). Note that the Lucas-Lehmer test is sufficient to
prove primality for numbers of this form, regardless of their
size. If Frink says that a Mersenne number is prime, it is.
factor[num] to detect Mersenne numbers
(that is, those of the form 2n-1) and use certain properties of
these numbers to speed factorization when n is composite. This
currently performs some recursive subdivision of the number, detecting
some known factors rapidly. This makes factoring some Mersenne numbers
much, much faster.
It should be noted that any calendar dates before October 15, 1582, (the date that the first countries switched from the Julian to the Gregorian calendar) should be treated as suspect when converting a Julian day to a Julian date or Gregorian date or vice versa. Not to mention the glitches in the proleptic leap year rules projected backwards, the fact that there was no year zero, and the fact that there was no Julian calendar before 4 AD. I need to figure out and state my policies as to what calendar dates before this mean (and probably make all the options of interpretation user-configurable.)
array.removeValue[value] method to
remove the first item having the specified value from the array. See the
Array Methods section of the
documentation for more.
new operator, e.g.
new Something instead of
new Something[] .
arctan[x,
y] to work with all combinations of intervals and real
numbers. This was an enormous pain. Thanks to G. William Walster for his
assistance in making this much less painful.
format[x, divideBy,
decPlaces] function to allow intervals to be formatted to the
specified number of decimal places.
format[x, divideBy,
decPlaces] function to be a string representing a more
complex expression (previously, it only allowed unit names.)
-> and in the format[x, divideBy,
decPlaces] function. This has the result that some complex
formatting done through the web-based interface will not work. This may
be weakened in the future.
0 -> m . Thanks to
the lovely David Rysdam for the report.
eval[string] return undef if
something goes wrong during parsing. Previously, it would throw an
exception and halt evaluation.
floor[x],
arccos[x], arcsec[x], and
arctan[x] to work with intervals.
mod operator to work with intervals.
This added a huge amount of power. All of a sudden, almost all of the astronomical calculations in my sun.frink libraries work with fuzziness and uncertainties.
infimum[x],
supremum[x], and mainValue[x]
functions to work on date intervals.
tan[x],
csc[x], sec[x], and
cot[x] to work with intervals and all of their
inflection points.
sin[x] and
cos[x] to work with intervals and all of their
inflection points.
sqrt[x], ln[x],
log[x], and exp[x] to work with intervals.
frink.errors.FrinkEvaluationException
when something goes wrong in the course of parsing or executing. If
you're integrating Frink into another program, you'll have to catch this
exception. This hopefully makes it easier to detect and handle error
cases. Previously, the error message just appeared in the output string,
which made it difficult to distinguish from normal program results.
See the documentation on Frink's
integration methods for more information.
infimum[x],
supremum[x], and mainValue[x] to
return the lower, upper, and main (middle) bounds of an interval. If these
functions are called with a unit that's not an interval, these just return
the unit.
< == >, etc) to
work with intervals. These operators try to Do The Right Thing when
applied to intervals. If you compare intervals that do not overlap, they
return the appropriate result. If, however, the intervals do
overlap, they terminate the program with an error similar to the following:
Comparison expression: Using operator > to compare intervals [2, 3] and 2.5.
This operator is only defined if there is no overlap between intervals.
Please modify your program to use interval-aware comparison operators.
CLT (certainly-less-than) and
PGE (possibly greater-or-equal).
1^x to always return the exact integer 1.
So what's interval arithmetic? It's a way of tracking errors or imprecise values automatically throughout your calculations. Check out the new section in the documentation about it.
Internally, the math libraries were rewritten extensively to allow rigorous interval arithmetic.
Currently, only the mathematical operators + - * / ^ are
implemented for intervals. The notation may also change in the future,
but it's already quite usable for many programs and calculations.
min[array] and max[array]
functions to return the smallest and largest items in an array
respectively.
new expressions to go just about anywhere in
expressions. These were somewhat limited before.
1.234e100 + 1 the answer would be calculated and
stored with all 100 digits, most of which were almost certainly illusory
digits of precision, and far more digits than were specified in the
original number. The result is now only calculated and stored to the
number of digits of working precision (by default 20, but you can
increase this by using the setPrecision[digits]
call.) Note that this does not affect integers or rationals,
which are still calculated with all of their digits.
mod function also
produces less digits of illusory precision when working with
floating-point numbers.
length[expr] function now returns the number of
items in an enumerating expression.
eval[] now disallows defining of functions in
untrusted code. (You can still do this in unsafeEval[]).
This may be relaxed in the future--it may be beneficial to allow users to
define functions that are marked as being defined in a restricted context
and would only be allowed to be called in the same restricted context.
But that'll take work. What this means for users of the web-based
interface is that they won't be allowed to define functions any more.
--sandbox command line option which enables Frink's
internal sandbox mode for untrusted code. See the Command-Line Options section of
the documentation for more.
<, >, =,
<=>, etc.) to make better comparisons when numbers were
really large or really small. Previously, there could be issues if
floating-point numbers were larger than about 10308or when
comparing very large and very-nearly-identical rational numbers or
comparing some numbers of different types (e.g. integers and rationals)
when the numbers were very large and almost identical.
Double.compareTo() which did not
exist before Java 1.2. This may have caused problems doing comparisons on
some handheld devices.
Numeric hierarchy so that they
would support the above.
.frink file extension and the
text/frink MIME type with the Frink program you just
downloaded. This simply allows you to edit files with the .frink file
extension by double-clicking them. This will not run the files,
but simply open them in editing mode. Java Web Start will also
never change the MIME associations used by your browser... the
MIME associations are only made for the operating system. If you don't want
this behavior, choose "no" when prompted by Java Web Start. (You can also
prevent associations from ever being made by setting your Java Web Start
preferences wherever that may reside on your system. In Windows, It's in
the Control Panel.)
hubbleconstant and H_0 units for the
expansion rate of the universe. These are based on WMAP data.
afghani, baht, balboa, birr, bolivar, boliviano, cedi, dalasi, denar, deutsche_mark, dobra, dong, drachma, euro, fin, florin, forint, gold_cordoba, gourde, guarani, hryvna, indonesia_rupiah, israel_new_shekel, italy_lira, kina, kroon, kuna, kwanza, lari, lat, lek, lempira, leone, lev, lilangeni, litas, loti, luigino, markka, metical, moldova_leu, morocco_dirham, naira, nakfa, new_dinar, new_dollar, new_shekel, ngultrum, norway_krone, nuevo_sol, ouguiya, pa'anga, pataca, peseta, pula, punt, quetzal, rand, real, riel, ringgit, rubel, ruble, rufiyaa, rupiah, schilling, somoni, switzerland_franc, taka, tenge, tolar, tughrik, vatu, yen, yuan_renminbi, zloty
Type sort[units[currency]] to get a list of all currencies
sorted by name, or ?currencyname to figure out what
country each of these comes from. Do you know?
-> operator where the
right-hand-side was a function that used a "return" statement. This may
have previously thrown a "Return used outside a function" error. For
example, 10 kilotons TNT -> Richtersovereigns_yyyy (with the trailing
"s") work properly. Before I just had sovereign_yyyy
entered twice. Thanks to the lovely Berrian (Eno)-(Van Fleet) for filing
a bug report so Zen-like and subtle that it was like it wasn't a bug
report at all. And thanks for the lovely comments about Frink.
randomBits[numBits] .
Fixed a bug in the function JacobiSymbol[a,n] which
returned the wrong value in some cases when a was negative and
within the range [-2147483648, -1]. (Values were correct for other values
of a.) Thanks to Aaron Bertram for the bug report.
I'd like to note, as an interesting aside, that I remembered that Sun had a similar bug in their calculation of the Jacobi Symbol. (I don't use their algorithm, by the way, so Frink's Jacobi symbol calculations will work properly in any JVM.) It took Sun three years to release a fix since the bug was first reported. (It was reported against Java 1.3.1, and not fixed until 1.5.) Many of their primality tests were broken due to this. (So much for your secure communications!)
To contrast, I got the bug report this morning, and I was ashamed that I didn't have time to fix it before I left for work. I had to wait until I got home to release a fix.
setEngineering[boolean] function to switch
back to the old "engineering" format. See the Setting Number Formats section
of the documentation for more details.
--nounits or -nu command-line option to
start Frink without parsing the standard units file.
/g modifier) where repeating the match may
cause null pointer exceptions.
flatten[list] function to allow enumerating
expressions to be passed in.
for loop of the form:
for [a,b] = enumeratingExpression[]
ARGS global variable which contains the values of
any command-line arguments following the name of the program.
There are some oddities and inconsitencies in NIST's data (and it's certainly not the first time I've found mistakes in NIST data.) For example, dividing their definition of electron mass in kilograms, their definition of the "unified atomic mass unit (u)", and the electron mass in u do not yield values that are self-consistent. They're close, but off in some significant figures. These sorts of errors and inconsistencies seem to go all through their data--values that are derived from other values, such as the fine structure constant α, or the Rydberg constant, show more precision than the values they are derived from, and the values derived from multiplying their published values aren't self-consistent.
editDistance[str1, str2] function
to calculate the edit distance or Levenshtein distance between two
strings. This can be used for a wide variety of purposes, including
performing fuzzy spelling checks, detecting plagiarism, or finding
correlations between strands of DNA. More information is available in the
Other String Functions
section of the documentation.
editDistance[str1, str2] function
allowed fuzzy spelling suggestions to be suggested in the hints provided by the
web interface. If a misspelled unit is entered in the web-based
interface, it will suggest alternates which have edit distances less than
1/3 the length of the longer word. (This matching is done in a
case-insensitive manner.)
min[arg1, arg2] and
max[arg1, arg2] functions. More
description can be found in the Other
Functions section of the documentation.
lines[] function. The
security check was deferred until the enumerator was actually accessed.
This meant that an enumerator could "leak" out of a secure context and its
security may not have been checked until later, when, say, its contents
were printed. I now check security repeatedly at several points. Many
thanks to 31337 |-|Ax0r Clayton O'Neil