Saving version 16.0.5 online as the author has passed away and his work must be preserved. In case soemthing evver happens to his projecct or website.

This commit is contained in:
Matthew Fillpot 2013-03-17 10:58:12 -04:00
commit ceb08616a4
184 changed files with 43168 additions and 0 deletions

29
AUTHORS Normal file
View File

@ -0,0 +1,29 @@
George Gesslein II <gesslein@mathomatic.org>
Chief Mathomatic creator, author, maintainer, and copyright holder.
http://www.mathomatic.org
There are many individuals maintaining Mathomatic ports. Thank you very much
for creating, supporting, and sponsoring the Mathomatic ports for all these
years.
Thanks to all people who have contributed code and time to the Mathomatic
project:
2010 Simon Geard for better and more readable code command code. :-)
2010 Michael Pogue of Sun Microsystems for help on compiling under Solaris.
2010 Jonathan Stark for the original cmake file "CMakeLists.txt".
2011 Doug Snead for the MinGW color mode code for cmd.exe and command.com.
2012 Doug Snead creates and sells a fancy Android version with a GUI.
Thanks to all the wonderful people that have been testing, contributing, and
donating to the Mathomatic project and encouraging me on; many are not listed
here. If you think you belong in this list, please let George Gesslein II
know. I will mention anyone that has contributed to or guided the Mathomatic
project, that wishes to be mentioned here. Please indicate how you would like
your entry to appear (website?, email address?).
And late thanks to Dennis M. Ritchie, whose work to design and create the
original C language and compiler made Mathomatic and our life possible. I
even learned C from his book.
Sincerely,
George Gesslein II

101
CMakeLists.txt Normal file
View File

@ -0,0 +1,101 @@
# cmake build file for Mathomatic and the Symbolic Math Library,
# originally contributed by Jonathan Stark.
# Produces the normal version of Mathomatic with readline support.
# If you need the Symbolic Math Library as a shared library,
# change the line "add_library(mathomatic_cmake" to:
# "add_library(mathomatic_cmake SHARED" below.
# This is all untested! It is recommended to use "makefile" instead!
# To use cmake instead of "makefile", type:
#
# cmake .
# make -f Makefile
#
# Please note that cmake makes an unfixable mess of the Mathomatic
# source distribution directory, so make a copy, first.
cmake_minimum_required(VERSION 2.6)
project(mathomatic)
file(READ VERSION FV)
string(STRIP ${FV} MATHOMATIC_VERSION)
message(STATUS VERSION: ${MATHOMATIC_VERSION})
add_definitions(-O3 -Wall -Wshadow -Wno-char-subscripts -fexceptions -DVERSION="${MATHOMATIC_VERSION}")
add_library(mathomatic_cmake
includes.h
standard.h
am.h
altproto.h
externs.h
blt.h
license.h
complex.h
proto.h
lib/mathomatic.h
lib/lib.c
globals.c
complex.c
poly.c
super.c
am.c
factor.c
help.c
list.c
unfactor.c
complex_lib.c
factor_int.c
simplify.c
cmds.c
diff.c
gcd.c
integrate.c
parse.c
solve.c
)
add_executable(testmain
lib/mathomatic.h
lib/testmain.c
)
add_dependencies(testmain
mathomatic_cmake
)
add_executable(mathomatic
includes.h
standard.h
am.h
altproto.h
externs.h
blt.h
license.h
complex.h
proto.h
globals.c
complex.c
poly.c
super.c
am.c
factor.c
help.c
list.c
unfactor.c
complex_lib.c
factor_int.c
main.c
simplify.c
cmds.c
diff.c
gcd.c
integrate.c
parse.c
solve.c
)
set_target_properties(mathomatic_cmake PROPERTIES COMPILE_FLAGS "-DLIBRARY")
set_target_properties(mathomatic PROPERTIES COMPILE_FLAGS "-DREADLINE -DUNIX")
target_link_libraries(mathomatic -lm -lreadline)
target_link_libraries(testmain mathomatic_cmake)
target_link_libraries(mathomatic_cmake -lm)

502
COPYING Normal file
View File

@ -0,0 +1,502 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

104
INSTALL.txt Normal file
View File

@ -0,0 +1,104 @@
Mathomatic Installation Instructions
------------------------------------
The requirements for easy installation from this source code are: the GNU
make utility and the GNU C compiler (gcc). Other C compilers may be used, but
may require small changes to the makefile, source files, or compilation
command-line. You will need to open a shell window to compile, install, and
run Mathomatic.
On a Debian or Ubuntu Linux computer, the "build-essential" and readline or
editline development packages "libreadline-dev" or "libeditline-dev" are
required to compile Mathomatic with readline functionality. To open a shell
window in desktop Linux, launch Applications/Accessories/Terminal.
To skip these compilation instructions and install an older version of
Mathomatic, already compiled and ready to run under Debian or Ubuntu, type:
sudo apt-get install mathomatic mathomatic-primes
at the shell prompt, then type your password if prompted for it. You can then
run Mathomatic by typing "mathomatic". This is possible because Mathomatic is
an official Debian package. It is also an official Fedora package. To install
Mathomatic in Fedora Linux, type:
sudo yum install mathomatic
To install Mathomatic in Gentoo Linux, type:
sudo emerge mathomatic
The Mathomatic code is portable, self-testing, and easily compiles and
installs using the GNU utilities under Linux, Unix, SunOS, Mac OS X,
Microsoft Windows, and many modern mobile devices. Both the source code and
compiled, ready to run, binary packages may be available from your operating
system's package manager or from the Mathomatic website:
http://www.mathomatic.org/math/download.html
Typical compilation and installation
------------------------------------
Root (super-user) authority is needed to install Mathomatic, because write
permission is needed to copy files into the directories in "/usr/local".
Mathomatic need not be installed to run the compiled executable. Reading the
makefile comments is recommended.
A typical compile/install is done by typing the following at the shell
prompt, while in the Mathomatic source code directory:
make clean
make READLINE=1 or make EDITLINE=1
make test
sudo make install
and enter your password. That will compile the source code with readline
enabled, test the functionality of the generated executable (named
"mathomatic"), and install the executable, docs, and tests in "/usr/local" in
less than a minute. After that, typing "man mathomatic" should bring up the
man page, and typing "mathomatic" should run Mathomatic. If Mathomatic
doesn't run, check that the PATH environment variable includes
"/usr/local/bin" with the shell command "echo $PATH".
To install in "/usr" instead of "/usr/local", type:
sudo make prefix=/usr install
sudo asks you for your password; if it doesn't work, login as root or type:
su -c "make install"
and enter the root password to install as the super-user.
m4 Mathomatic
-------------
To install everything, including m4 Mathomatic (rmath), which allows easy
entry of math functions like sqrt(x) and sin(x) as macros, use "make
m4install" or "make m4install-degrees" instead of "make install". "make
m4install-degrees" sets degree mode instead of radian mode for trig
functions.
Prime Number Tools
------------------
To clean, compile, test, and install the Mathomatic Prime Number Tools:
cd primes
make flush
make
./t
sudo make install
Uninstall
---------
To undo the installation, removing Mathomatic from the local computer, type:
sudo make uninstall
These instructions were written by George Gesslein II of www.mathomatic.org

437
NEWS Normal file
View File

@ -0,0 +1,437 @@
The latest version of Mathomatic is 16.0.5, here are the changes:
CHANGES MADE TO MATHOMATIC 16.0.4 TO BRING IT UP TO THE NEXT VERSION:
09/17/12 - Corrected and improved "tests/finance.in" and the terminology used,
thanks to Wolfram Alpha.
09/20/12 - Fixed "./update" command (which updates "proto.h") to work without
the readline development headers and libraries installed.
09/23/12 - m4/gradians.m4 copied with m4/functions.m4, when installing with
"make m4install" into "/usr/local/share/mathomatic/m4/",
so gradian trig mode can be used by typing "rmath gradians.m4"
at the shell prompt, while in that directory.
The debug level was being set in degrees.m4
and gradians.m4; no longer.
09/25/12 - Mathomatic now always runs "set load" after "set save",
for the convenience of immediately loading the specified settings,
and for error checking.
From now on Mathomatic does not set the alarm nor hangup handlers,
because it crashes the entire shell window when readline
is compiled in and an alarm or hangup signal happens.
Works acceptably now that these signal handlers are not set,
it just quits when time is up, saying "Alarm clock";
The same thing happens for SIGHUP, except it just says "Hangup"
and quits. I am really not liking readline nor its license now.
SIGALRM and SIGHUP are no longer given handlers. The default
seems to be what has to be there with the current readline mess.
Overwriting the current signal handlers causes serious bugs,
but only for readline.
09/29/12 - Fixed "lib/compile.testmain" to work with the latest linker.
10/16/12 - Made all output methods respect "set columns", so
"display all >output.txt" will not always use infinite columns.
This goes for the Symbolic Math Library, too.
Mathomatic version 16.0.5 released Sunday 10/21/12.
CHANGES MADE TO MATHOMATIC 16.0.3 TO BRING IT UP TO THE NEXT VERSION:
09/09/12 - Allow use of editline library in Mathomatic, because somehow
use of GPL libraries in LGPL code is not allowed, and GNU readline
is GPL. I am so confused about this Debian bug#687063:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=687063
Based on the bug report's information sources,
it appears he is saying the truth about this license issue,
so I will have to upload new versions of
Mathomatic with editline instead of readline to Debian.
The only noticeable difference should be it doesn't save
the history between Mathomatic sessions.
I will comply with all that request it,
though most distributions do not include editline,
which has no major licensing restrictions. Readline is still
perfectly usable and good as before, you just have to link
it in yourself.
09/10/12 - Going to have to make a new release already, 2 days after the last
one, so I can upload this readline licensing fix to Debian by
linking with editline. There is no reason for anyone to upgrade
to version 16.0.4, unless you wish to link with editline instead
of readline. The proper code has been added. All you have to do
is have the editline libraries loaded on your system,
and run "make EDITLINE=1" to compile and link Mathomatic with
editline.
Mathomatic version 16.0.4 released Monday 09/10/12.
CHANGES MADE TO MATHOMATIC 16.0.2 TO BRING IT UP TO THE NEXT VERSION:
New command "set load" loads the current set options startup file again,
displaying the startup file as it reads it in.
If the file doesn't exist, or something is wrong, then an error message is
displayed and the set command returns with failure.
Accidently putting "load" in the startup file is now handled correctly.
08/09/12 - Allow "matho-primes all" and the command "list primes all" in
Mathomatic to continually output consecutive prime numbers.
08/12/12 - Fixed any rman errors in the makefile so they won't be ignored.
08/17/12 - rmath and matho no longer set the debug_level or modulus_mode,
so they can be set by the startup options file.
08/19/12 - Allow the repeat prefix on the approximate command, making it
approximate and simplify as much as the calculate command
does. Hopefully someday it will just give a temporary
result, too. Numerical input into the symbolic math library
now uses "repeat approximate" instead of just "approximate"
to approximate the user's input, so the result is the
same as the Mathomatic application's result.
Disallow the same warnings to be repeatedly displayed, if the
current warning is the same as the previous warning.
08/20/12 - Allow directory names as read command arguments, instructing
the read command to change the current directory to the specified
directory. Without any arguments, the read command now does an
"ls" command in Unix/Linux, and "dir" under MS-Windows, listing
the current directory contents. Running Mathomatic with a
directory name argument now conveniently changes directory to
that directory, then gives you the main prompt.
08/28/12 - Made "integer" type variables much more useful. For example,
the following now happens generally:
1-> i^(4*integer)
#1: i^(4*integer)
1-> simplify
#1: 1
1-> i^((4*integer) + 1)
#2: i^((4*integer) + 1)
2-> simplify
#2: i
2-> i^((4*integer) + 2)
#3: i^((4*integer) + 2)
3-> simplify
#3: -1
3-> i^((4*integer) + 3)
#4: i^((4*integer) + 3)
4-> simplify
#4: -1*i
08/29/12 - Displays "Calculating..." whenever autocalc is used now.
08/30/12 - Added ability to set the normal text color.
Still defaults to no color. Use "set color 0" to set the normal
text color to green, as it has been for many years in the past.
08/31/12 - Removed the "set preserve_surds" option, since the approximate
and calculate commands all take care of undoing that.
The code remains, however "set preserve_surds" is no longer
advertised. I have never used it.
Surds are preserved, for accuracy's sake, by default.
09/05/12 - "set" as a null set option works now, so no one will have any
trouble setting-up the set options startup file.
Mathomatic version 16.0.3 released Saturday 09/08/12.
CHANGES MADE TO MATHOMATIC 16.0.1 TO BRING IT UP TO THE NEXT VERSION:
A nice cleanup and documenting of everything, while my mind still works.
07/23/12 - Enabled links in "manual.pdf" (the Mathomatic User Guide
and Command Reference), they were not working well before,
so I had disabled all links, but they work great now.
07/24/12 - Allow -a option ("set alternative") with sets alternative
color mode, useful in MS-Windows when using Cygwin with the
MinGW compiled version.
07/27/12 - Two bug fixes today:
Fixed using rlwrap under Cygwin and possibly other places,
when running rmath.
get_yes_no() question asker wasn't working in Cygwin or rmath.
Fixed to always ask the question, even if the input is not a TTY.
07/28/12 - Reading directories and empty files gives an error now.
07/30/12 - Split off changes.txt to changes.txt and changes_series_15.txt.
changes.txt and NEWS now contain only series 16 changes.
Added tests/batman_gnuplot_bug.in to prove there is a plotting bug
in gnuplot itself.
08/01/12 - Removed directive to use large font in the CSS for all Mathomatic
documentation. This is so it can be browsed easily with a mobile
device. The font size should be set by the user.
08/02/12 - A one-sided expression with an equals sign now only sets the
expression equal to zero if autocalc didn't work on it. In the
Symbolic Math Library, or without autocalc enabled, all is the
same. This makes it more likely purely numerical input is only
calculated, even when preceded or followed by an equals sign,
when autocalc is enabled. Reason for this change:
Why would you want to set a constant equal to 0?
Fixed a bunch more error reporting bugs coded into version 16.0.1
of Mathomatic to apply identical operations to both sides of an
equation. All fixed now. Points to the error correctly now, too.
08/04/12 - Major change to Symbolic Math Library. It now works exactly like
the application when it comes to purely numerical input,
approximating and displaying the result, however sign variables
are not expanded and the result is not 100% simplified,
so running "simplify sign" afterwards helps with that.
To revert to the old way, just turn off autocalc, or set
the numerical input equal to some normal variable; then there
will be no automatic approximation nor simplification.
You can tell when an input has been approximated because it
was numerical input, because it will always be preceded with
"answer =".
08/05/12 - m4/degrees.m4 copied with m4/functions.m4, when installing with
"make m4install", thanks to a suggestion by Reini Urban,
maintainer of the Cygwin version.
Mathomatic version 16.0.2 released Monday 08/06/12.
CHANGES MADE TO MATHOMATIC 16.0.0 TO BRING IT UP TO THE NEXT VERSION:
07/06/12 - Confirmed successful compilation and testing with the
Tiny C compiler (tcc). Only needed to set the tcc linker
library directories to the current gcc library directories
to make it work (using the -L option).
Searched globally for the word "simply" and fixed many outdated
texts in the Mathomatic documentation and READMEs, deleting some
wrongly used "simply"s, too.
07/07/12 - Allow "set modulus_mode language", where language is C, Java,
Python, or positive.
07/08/12 - Now leaving the "UNIX" C preprocessor define alone,
when "HANDHELD" is defined. "UNIX" was previously
forced undefined.
07/11/12 - "make test", "make check", and ./t now display the actual
Mathomatic version number being tested.
matho-primes now has a -v (display version number) option,
like Mathomatic does.
Mathomatic now automatically clears out all old
numeric calculations if it runs out of equation spaces,
requiring no action from the user.
07/12/12 - The solve command never needs the "repeat solve" prefix anymore.
The repeat flag is always set for the solve command, so that
it will always do full simplifies when verifying.
Added quadratic formula derivation and proof to
"tests/quadratic.in".
07/17/12 - I came up with a swinging new and easy way to add, subtract,
multiply, divide, modular and integer divide,
and raise to the power of both sides of an equation by any
expression. To add x+1 to both sides of the current
equation, just type "+=x+1" at the main prompt. To divide both
sides by c^2, type "/=c^2". You can add stuff to non-equations
too, this way. Be sure and use the simplify command after this
if needed, because only a small amount of simplification is done
by default, just enough so you can see what is happening.
07/20/12 - Changed floating point to rational floating point conversion
routine (f_to_fraction()) to ignore converting anything with
over 15 digits, for greater accuracy.
This fixes some small accuracy bugs: "factor number 17!" now gives
an error instead of the wrong value.
07/21/12 - Integrate, Laplace, and Numerical Integrate commands now warn
when the current equation is not a properly solved equation.
Mathomatic version 16.0.1 released Sunday 07/22/12.
CHANGES MADE TO MATHOMATIC 15.8.5 TO BRING IT UP TO THE NEXT VERSION:
Code, documentation, and user interface improvements, corrections,
and cleanup. Fixed many possible bugs, some where the wrong level global
expression buffers were being used.
05/26/12 - Push command improved with better responses. Same functionality.
In the source code, tune-up variable integer_coefficients was
renamed to "factor_out_all_numeric_gcds", because Mathomatic always
tries to have integer coefficients this year, but it doesn't always
factor out all numeric GCDs unless factor_out_all_numeric_gcds
is true, or the factor command is used. The default is false,
for more orderly and revealing coefficients.
Of course, much of what Mathomatic does is
try to improve readability and simplicity.
There is no need to set this variable, just use the factor command.
05/27/12 - Removed C declarations for memmove(3), the defaults in
/usr/include/string.h are probably better and what's wanted in
every case. It would be very odd if this didn't work 100%.
05/28/12 - readline history file renamed to "~/.matho_history" from
"~/.mathomatic_history". File name was too long for CygWin.
Tested thoroughly compiling, installing, and running under
the latest CygWin. Works fine, except for rlwrap. "rlwrap -v"
returns with error, a successful return is how I test for its
existence.
Made output redirection work with the "list primes" command.
06/02/12 - Cleanup of Linux, Mac OS X, and Windows binary distributions.
The Windows binary distribution now includes m4 scripts, in case
CygWin is installed, allowing use of m4 Mathomatic in Windows.
Fixed MinGW version to not output two carriage returns at the
end of every line of list command output.
06/03/12 - If compiled with -DSHOW_RESOURCES, will give total CPU usage and
RSS size in the "version status" command. Requires OS support.
Some OSes will show even more information. Uses getrusage(2).
06/04/12 - Allow breaking out of user line-input requests with Control-C.
Still have to hit the Enter key, but the command will be aborted.
06/05/12 - Added "lib/example.c", the simplest example yet of Symbolic Math
Library usage. Compile with "compile.testmain" or practice
compiling it by hand.
The simplify command now returns the number of expressions
simplified, so you can tell if "simplify sign" worked.
The solve command can now require verification, by using the
"verifiable" option, instead of the "verify" option. This causes
unverifiable solves to return with failure, aborting any reads.
Fixed missing code in internal C function free_mem().
I don't think it was used by anyone. A call to free_mem() is
now made on exit, if Mathomatic is compiled with -DVALGRIND, to
check for memory leaks.
06/08/12 - Added polynomial factoring to GCD result of divide command.
It is always handy to know what the factors are of the GCD.
Allow comma (,) at the end of most input lines. A comma now
terminates an expression instead of giving an error. Allow
commas all over the place, where-ever logical, in any
Mathomatic command-line. They are used as separators,
more so than spaces.
06/09/12 - Cleaned up variables command to always allow the count parameter,
and to line up everything with 8 character wide tabs.
Added ability to place the definite integration bounds on the
integrate command-line, just like the nintegrate command.
Added titles to most help command pages.
06/10/12 - The "factor number" command works much nicer now, and allows comma
separators and zero.
Developers should note that to remain the same as past versions,
HTML mode needs to be "set html all" to output HTML at all times
in both the application and the symbolic math library, even when
redirecting output. Now setting all HTML mode with
"make pdfsheet". "set html" only outputs HTML code to standard
output.
06/13/12 - Added warning in "misc/known_bugs.txt" about LLVM/Clang optimizer
failure when compiling Mathomatic with LLVM/Clang instead of gcc.
If you enable any optimization at all, entering (32^.5) and the
like will hang Mathomatic, putting it in an endless loop.
So when compiling Mathomatic with LLVM/Clang, always disable
optimization with "-O0", so that it will then run and pass
all of the tests in 1 second and not be infinitely slower.
Mathomatic will hang during "make test"
if compiled with optimization enabled using LLVM. Mathomatic is
not noticeably slower when compiled without any optimization,
because everything is memmove(3)s and floating point arithmetic.
06/15/12 - Added repeat option to replace command. A handy feature that
lets you try plugging different values into an equation. It
checks if the result is an identity, too.
06/18/12 - The version command now has a "status" option, which behaves
as before, displaying all version and status information.
The version command by itself now only displays the Mathomatic
version number. Running "mathomatic -v" is now a good way of
testing for the existence of Mathomatic on your system, only
outputting the version number to standard output and exiting
successfully.
06/19/12 - Removed the parenthesizing of variable names in all messages.
If the current expression is a non-equation, then prefixing or
suffixing an expression with "=" will add that expression as
the other equation side now, conveniently making it an equation
you can solve.
06/22/12 - Added equation number ranges option to tally command. Type
"tally -" to resume if the current equation hasn't changed. Type
"tally all" to add together all stored expressions as the starting
value. Specifying equation numbers or ranges will silently add
them, then prompt for the next things to add. The average option
now displays the number of entries (count) each time the average
is displayed. When you exit by typing an empty line, the current
total is saved in the next available equation space and made
current, so it can easily resume with "tally -". "-" by itself
always means the current equation.
gnuplot now works with MS-Windows better. Tried running a Windows
gnuplot test from scratch, without Cygwin, and it didn't work.
It should be mostly fixed now. So go ahead and try plotting
in Windows, after downloading and installing gnuplot. Please
complain if any problems.
Fixed a long-running problem with the plot command, by asking the
user questions, only if needed, so that gnuplot will not give an
error if you are multi-expression plotting.
06/23/12 - Moved load_rc() out of main.c so that the Mathomatic startup set
options file can be loaded by the library, if the developer wishes.
Changed a few things so that "set save" and "set no save" will work
if load_rc() is called beforehand.
06/25/12 - The simplify command has been fixed for optimal integer coefficient
factoring results and so "180*(sides-2)" simplification works
nicely, by keeping the result the same as the start by
factoring out rational constants greater than 1 (this is new),
along with less than 1,
if the coefficients remain or become integers.
Many things cleaned up and finished, like the official
documentation, the "code integer" command, and "examples/fact.c".
06/27/12 - Allow an ASCII string after the "set save" command, to save only
that string in ~/.mathomaticrc, so that string, which should be set
options, is for every Mathomatic session to start with.
For example, "set save bold color" will start out Mathomatic in
bold color mode every time. Enter "set no save" to remove.
"set save" by itself saves all of the current set options for every
future session.
Mathomatic version 16.0.0 released Friday 06/29/12.
----------------------------------------------------------------------
End of this version history of the Mathomatic computer algebra system.
Current as of 10/21/12 (2012-10-21).
The latest changes are at the beginning of this file.
This file is always available up-to-date at http://mathomatic.org/NEWS
Alternatively, you can get it at http://mathomatic.orgserve.de/NEWS
Do not edit this file, edit the end of changes.txt instead.
Written and maintained by George Gesslein II.

320
README.txt Normal file
View File

@ -0,0 +1,320 @@
Mathomatic
Computer Algebra System
This file can be found in the Mathomatic source code directory, or at
http://mathomatic.org/README.txt for the most recent version.
This archive contains the complete C source code and documentation for
Mathomatic, the automatic algebraic manipulator. Mathomatic compiles and runs
under any operating system with a C compiler and is very portable. There are
no dependencies other than the standard C libraries. Using the GNU make
utility or shell scripts, this text mode application should compile with the
GNU C compiler (gcc), Tiny C compiler (tcc), or MinGW, and run correctly
under Linux, Unix, Mac OS X, Microsoft Windows, and many mobile devices,
without any modifications, except to the compile/install command-lines.
Most of the Mathomatic code can also be called from any C compatible program,
when linked with Mathomatic specially compiled as a symbolic math library
(see directory "lib").
Mathomatic is a free, portable, general-purpose Computer Algebra System (CAS)
and calculator software that can symbolically solve, simplify, combine, and
compare algebraic equations, simultaneously performing generalized standard,
complex number, modular, and polynomial arithmetic, as needed. It does some
calculus and is very easy to compile/install, learn, and use. Plotting
expressions with gnuplot is also supported.
New users: try typing "help examples". There are many interesting Mathomatic
scripts in the "tests" directory, that show what Mathomatic can do, and they
teach some mathematics, too.
Licenses
--------
All Mathomatic software and documentation in this archive are copyrighted.
The Mathomatic documentation in the "doc" directory is licensed under the GNU
Free Documentation License (GFDL) version 1.3, with no Invariant Sections, no
Front-Cover Texts, and no Back-Cover Texts, so it can be easily published,
corrected, and translated by anyone.
The Mathomatic software and all else are licensed under the GNU Lesser
General Public License (LGPL) version 2.1 (see file "COPYING" for the full
text of the license). That means Mathomatic is free software and comes with
no warranty at all, but if you find any errors in it, I will try to fix it.
LGPL also means that even closed-source, proprietary software can include and
make use of the Mathomatic symbolic math library, but please tell the chief
author (George Gesslein II) if you are using Mathomatic in your software.
Compilation
-----------
This section can be skipped; you may wish to jump to the next section with
short compile/install instructions or read the file "INSTALL.txt", if you
only wish to install Mathomatic.
On a Debian or Ubuntu Linux computer, the "build-essential" and readline
development packages "libreadline-dev" are required to compile Mathomatic
with readline functionality. To open a shell window in desktop Linux, launch
Applications/Accessories/Terminal. Makefiles are text files named "makefile",
read by GNU make, used to build and install software as requested and needed;
reading the comments contained within them is often helpful when using
makefiles.
The latest Mathomatic source code may be downloaded from:
http://www.mathomatic.org/math/download.html
To extract and use the Mathomatic source code archive, make a new directory,
copy the archive to it and change directory to it, and extract the archive
with the unzip or tar utilities. unzip and tar extract to the current
directory, so be sure to change directory (cd) to where you want it, before
extracting. With "am.zip", be sure it is an empty directory, or you will end
up with a mix of many files and directories. All other archives on
Mathomatic.org properly put the files under a single directory created by the
archive, but "am.zip" puts many files in the current directory and a few
subdirectories.
To compile Mathomatic without readline support, type the name of the GNU make
utility (either "make" or "gmake", depending on the operating system) at the
shell prompt while in the Mathomatic source code directory. This will compile
the C source code using the instructions in file "makefile" to create the
executable file named "mathomatic". To run Mathomatic, type "./mathomatic" at
the shell prompt. No other files are needed to run Mathomatic, so the
executable can be copied to anywhere you like.
To test most functionality, type "make test" or "./t". If no errors are
encountered, "All tests passed 100% correctly." will be displayed, along with
the total run time. Otherwise the differences from the expected output will
be displayed.
To recompile with readline, which allows editing and history recall of all
Mathomatic line input by pressing the arrow keys, type:
make clean
make READLINE=1
That allows use of the cursor keys to recall and edit previously entered and
pushed expressions when running Mathomatic. A readline library must be
installed to compile for and use readline.
To create the compile-time secure version of Mathomatic, with readline
functionality and no file I/O nor shelling out possible, type:
./compile.secure
That will create the executable "mathomatic_secure", which can safely be used
as a telnet application or CGI program. The run-time security option
"mathomatic -s4" functions the same as "mathomatic_secure", so this secure
version compilation is not ever required.
Installation
------------
A typical compile/install is done by typing the following at the shell
prompt, while in the Mathomatic source code directory:
make clean
make READLINE=1
make test
sudo make m4install
That will compile the source code with readline enabled, test the
functionality of the generated executable (named "mathomatic"), and install
all executables, docs, and tests in "/usr/local" in less than a minute.
To clean, compile, test, and install the Mathomatic Prime Number Tools:
cd primes
make flush
make
./t
sudo make install
To restore the Mathomatic distribution directory to pristine condition, type:
make distclean
To uninstall all installed Mathomatic files from the local computer, type:
sudo make uninstall
-----------------------------------------------------------------------------
There are quite a few math goodies in this archive, besides the main
Mathomatic program:
The directory "doc" contains the Mathomatic User documentation in HTML.
The directory "examples" contains example source code in C and Python.
The directory "icons" contains Mathomatic icons for your desktop.
The directory "lib" contains the API and test for the Mathomatic library.
The directory "m4" contains the m4 (macro) Mathomatic supporting files.
The directory "menu" contains the Debian Menu System files for Mathomatic.
The directory "misc" contains a bug list and an idea list, etc.
The directory "primes" contains a prime number generator utility, etc.
The directory "tests" contains Mathomatic test and example scripts.
The "tests" directory is a good directory to visit to learn things about math
and Mathomatic.
For quick help while running Mathomatic, type "?" or use the help command. To
read or print the user documentation, point your web browser to the file
"doc/index.html", or "/usr/local/share/doc/mathomatic/html/index.html" if
Mathomatic was installed. When copying the Mathomatic documentation, please
copy the entire doc or html directory, not just selected HTML files from it.
For the most recent source code, binaries, documentation, information, and
other help, please visit the Mathomatic website: "http://www.mathomatic.org",
or its mirror site "http://mathomatic.orgserve.de/math/".
This README was written by George Gesslein II, chief author and maintainer of
Mathomatic:
email:
gesslein@mathomatic.org or
georgegesslein@gmail.com
postal address:
George Gesslein II
P.O. Box 224
Lansing, New York 14882-0224
USA
The author is happy to help people and other gentle beings with any problems
using this software. If you get stuck or find an error, send email to George
Gesslein II.
Please report suspected bugs in Mathomatic to the author via email, or on the
Launchpad website: "https://launchpad.net/mathomatic". Launchpad features a
complete bug management system. Mathomatic should always give correct,
simple, and beautiful answers; if not, please report it.
Many thanks to Jochen Plumeyer ("http://www.plumeyer.org") for donating
server space and services on the mirror site for a very long time. See the
"AUTHORS" file for people who have contributed code back to the Mathomatic
project.
Compile-time defines for the Mathomatic source code
---------------------------------------------------
To compile Mathomatic for a desktop operating system like Unix, GNU/Linux,
Mac OS X, or any POSIX compliant OS, define UNIX on the C compiler command
line with "-DUNIX". To compile Mathomatic for a generic system, simply
compile with none of these defines. To compile for Microsoft Windows with the
MinGW gcc compiler, define MINGW for a completely stand-alone executable. To
compile for Microsoft Windows using CygWin, define CYGWIN; note that
compiling for CygWin will require the presence of CygWin to run the resulting
executable. To compile for embedded systems, or handhelds like the Nintendo
DS, or smartphones like the iPhone and Android, define HANDHELD for reduced
memory usage.
Define READLINE and include the readline libraries at link time to use
readline mode, allowing easy command-line editing and history recall by
pressing the arrow keys. The readline development package must be installed
to compile with this option and the readline library must be installed to run
the resulting executable.
Define DEBUG for more code correctness checking, more error checking, and
easier debugging. With DEBUG, entering Control-C will ask if you wish to
change the debug level or abort. Mathomatic will run slower with DEBUG
enabled. Never define DEBUG for a public release. This define has nothing to
do with the debug level ("set debug").
Define SILENT to *not* display most error messages, all helpful messages,
warnings, and debugging output code. This is useful when using Mathomatic in
another program or if you only want terse output. Code size is reduced with
this option and you will not be able to set a debug level. Setting the debug
level to -1 with the Mathomatic command "set debug -1" is another way to not
display helpful messages. "set debug -2" will not even display any warnings.
Define LIBRARY to compile the Mathomatic code as a symbolic math library, so
that the Mathomatic symbolic math engine may be used in any C compatible
program. SILENT=1 is automatically defined when LIBRARY is defined, because
the library usually works silently, with any display done by the developer's
code. To enable debugging and output of messages in the library, define
SILENT=0. See the directory "lib" for the library hooks (API) and
test/example program and how to compile it (there is an easy to use makefile
for this, read "lib/README.txt").
Define SECURE for no file I/O nor forking, to disable all file reading,
writing, and executing, except for I/O to standard input/output/error (the
default files in any C program, used for input, output, and displaying
errors). This is useful when making Mathomatic available to the public
through telnet or CGI programs. It is also useful when making ROMable or
stand-alone code. All insecure commands and code are omitted when SECURE is
defined. See file "compile.secure", which is the secure Mathomatic build
script. The run-time option -s4 does the same thing and makes this special
compilation for security unnecessary.
Define TIMEOUT_SECONDS to set the maximum number of seconds Mathomatic may
run. Upon timeout, Mathomatic properly exits. This is useful when making
Mathomatic a telnet or CGI program, so it won't overload or tie-up the
server.
Define HANDHELD when compiling for embedded systems, or handheld devices like
the iPhone or Android. Currently, this only reduces the maximum memory usage
by reducing maximum size of expressions. The default expression array size
will be reduced to be 6 times smaller to accommodate the smaller RAM size of
handhelds.
The I18N define is meant to enable internationalization using gettext(3).
Currently all strings to be translated have been marked with _(string), but
no translations have been made, so Mathomatic is only available in English.
gettext(3) translations may not be possible, because they may require the
Unicode character set and GNU automake, I think. Or a lot of work on the
makefile, and maybe the source code.
Define NO_COLOR to default to color mode off. Define BOLD_COLOR to default to
bold color mode. Otherwise the default is non-bold color mode on. The
Symbolic Math Library defaults to color mode off (NO_COLOR).
To see which of the above defines were used in a compiled version of
Mathomatic, use the "version status" command.
Mathomatic C source code files
------------------------------
altproto.h - alternate proto.h, function prototypes, made by hand
am.h - the main include file for Mathomatic, contains tunable parameters
blt.h - the fast memory copy routine, allows overlapping copies
complex.h - floating point complex number arithmetic function prototypes
externs.h - global variable extern definitions, from globals.c
includes.h - automatically includes all necessary include files
license.h - the current Mathomatic software license notice
proto.h - all global function prototypes, made with cproto utility
standard.h - a generally useful include file for C math programs
am.c - standard routines for Mathomatic
cmds.c - code for commands that don't belong anywhere else
complex.c - floating point complex number routines for Mathomatic
complex_lib.c - generic floating point complex number arithmetic library
diff.c - symbolic differentiation routines and related commands
factor.c - symbolic factorizing routines (not polynomial factoring)
factor_int.c - floating point constant factorizing routines
gcd.c - general floating point GCD and numerical fractions code
globals.c - global variable and array definitions, duped in externs.h
help.c - command table, help command, and input parsing routines
integrate.c - integration routines and commands
list.c - expression and equation display routines
main.c - startup code for Mathomatic, not used for library
parse.c - mathematical expression parsing routines
poly.c - simplifying and polynomial routines
simplify.c - simplifying routines
solve.c - symbolic solving routines
super.c - group and combine denominators of symbolic fractions
unfactor.c - symbolic unfactorizing (expanding) routines
Symbolic math library interface source code files
-------------------------------------------------
lib/mathomatic.h - include file for user programs
lib/lib.c - commented Mathomatic symbolic math engine API
lib/testmain.c - test and example program main() to link with library

1
VERSION Normal file
View File

@ -0,0 +1 @@
16.0.5

31
altproto.h Normal file
View File

@ -0,0 +1,31 @@
/*
* Alternate global C function prototypes for Mathomatic.
*
* Copyright (C) 1987-2012 George Gesslein II.
*/
/* command function list */
int clear_cmd(), quit_cmd(), list_cmd(), simplify_cmd(), help_cmd(), eliminate_cmd();
int fraction_cmd(), unfactor_cmd(), compare_cmd(), extrema_cmd();
int read_cmd(), display_cmd(), calculate_cmd(), solve_cmd();
int factor_cmd(), derivative_cmd(), replace_cmd(), approximate_cmd();
int save_cmd(), taylor_cmd(), limit_cmd(), echo_cmd(), plot_cmd();
int copy_cmd(), divide_cmd(), pause_cmd(), version_cmd();
int edit_cmd(), real_cmd(), imaginary_cmd(), tally_cmd();
int roots_cmd(), set_cmd(), variables_cmd(), code_cmd(), optimize_cmd(), push_cmd(), push_en();
int sum_cmd(), product_cmd(), for_cmd(), integrate_cmd(), nintegrate_cmd(), laplace_cmd();
/* various functions that don't return int */
char *dirname_win();
char *skip_space(), *skip_comma_space(), *skip_param();
char *get_string();
char *parse_equation(), *parse_section(), *parse_var(), *parse_var2(), *parse_expr();
char *list_expression(), *list_equation(), *flist_equation_string();
double gcd(), gcd_verified(), my_round(), multiply_out_unique();
long decstrtol(), max_memory_usage();
void fphandler(int sig);
void inthandler(int sig);
void alarmhandler(int sig);
void exithandler(int sig);
void resizehandler(int sig);

1656
am.c Normal file

File diff suppressed because it is too large Load Diff

201
am.h Normal file
View File

@ -0,0 +1,201 @@
/*
* Main include file for Mathomatic. Can be edited.
*
* Copyright (C) 1987-2012 George Gesslein II.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
#ifndef DBL_DIG
#error "DBL_DIG not defined!"
#elif DBL_DIG != 15
#warning "DBL_DIG (the number of digits precision of doubles) is not 15."
#warning "This might be a problem."
#endif
#if sun
#define INFINITY_NAME "Infinity" /* set this to the name of the infinity constant as displayed by printf(3) */
#define NAN_NAME "NaN" /* set this to the name of the NaN constant as displayed by printf(3) */
#else
#define INFINITY_NAME "inf" /* set this to the name of the infinity constant as displayed by printf(3) */
#define NAN_NAME "nan" /* set this to the name of the NaN constant as displayed by printf(3) */
#endif
#ifndef PATH_MAX /* make sure the maximum file pathname length is set */
#define PATH_MAX 4096
#endif
#define MAX_K_INTEGER 1.0e15 /* maximum safely representable floating point integer, 15 digits for doubles */
#define always_positive(power) (fmod((double) (power), 2.0) == 0.0) /* true if all real numbers raised to "power" result in positive, real numbers */
#if I18N /* Internationalization: allow output in languages other than English using gettext(3). */
#define _(str) gettext(str)
#else
#define _(str) str /* Constant strings to be translated should be marked with this macro. */
/* Don't bother marking debug and fatal bug error strings. */
#endif
#define STANDARD_SCREEN_COLUMNS 80 /* default number of columns of characters on the screen */
#define STANDARD_SCREEN_ROWS 24 /* default number of lines on the screen */
#define TEXT_ROWS STANDARD_SCREEN_ROWS /* number of lines per page in the symbolic math library */
#define TEXT_COLUMNS STANDARD_SCREEN_COLUMNS /* default number of columns per page in the symbolic math library */
#define TMP_FILE "/tmp/mathomatic.XXXXXX" /* temporary file template for mkstemp(3) */
#define PROMPT_STR "-> " /* user interface main prompt strings, preceded by the current equation number */
#define HTML_PROMPT_STR "&minus;&gt; " /* main prompt in HTML output mode, should be same number of columns as above */
#define MAX_CMD_LEN min((max(PATH_MAX, 1024)), 16384) /* Maximum Mathomatic main prompt command-line length */
/* (not expression input, which can be much larger); */
/* also max filename length. */
#define MAX_PROMPT_LEN STANDARD_SCREEN_COLUMNS /* maximum length of prompts, limited to fit on normal terminals */
/*
* What follows is the definition of each array element in a mathematical expression,
* as stored internally by Mathomatic.
* Each mathematical expression is stored in a fixed-size array of token_type.
*/
enum kind_list { /* kinds of expression tokens specified in the union below */
CONSTANT,
VARIABLE,
OPERATOR
};
typedef union {
double constant; /* internal storage for Mathomatic numerical constants */
long variable; /* internal storage for Mathomatic variables */
/* Predefined special variables follow (order is important): */
#define V_NULL 0L /* null variable, should never be stored in an expression */
#define V_E 1L /* the symbolic, universal constant "e" or "e#" */
#define V_PI 2L /* the symbolic, universal constant "pi" or "pi#" */
#define IMAGINARY 3L /* the imaginary constant "i" or "i#" */
#define SIGN 4L /* for two-valued "sign" variables, numeric variables should be before this */
#define MATCH_ANY 5L /* match any variable (wild-card variable) */
#define V_INTEGER_PREFIX "integer" /* prefix for the integer variable type */
int operatr; /* internal storage for Mathomatic operators */
/* Valid operators follow (in precedence order), 0 is reserved for no operator: */
#define PLUS 1 /* a + b */
#define MINUS 2 /* a - b */
#define NEGATE 3 /* special parser operator not seen outside parser */
#define TIMES 4 /* a * b */
#define DIVIDE 5 /* a / b */
#define MODULUS 6 /* a % b */
#define IDIVIDE 7 /* a // b */
#define POWER 8 /* a ^ b */
#define FACTORIAL 9 /* a! */
} storage_type;
typedef struct { /* storage structure for each token in an expression */
enum kind_list kind; /* kind of token */
int level; /* level of parentheses, origin 1 */
storage_type token; /* the actual token */
} token_type;
/*
* The following defines the maximum number of equation spaces that can be allocated.
* The equation spaces are not allocated unless they are used or skipped over.
* This affects maximum memory usage.
*/
#ifndef N_EQUATIONS
#define N_EQUATIONS 200
#endif
/*
* The following defines the default maximum mathematical expression size.
* Expression arrays are allocated with this size by default,
* there are 2 of these for each equation space (1 for LHS and 1 for RHS).
* DEFAULT_N_TOKENS is linearly related to the actual memory usage of Mathomatic.
* This should be made much smaller for handhelds and embedded systems.
* Do not set to less than 100.
*/
#ifndef DEFAULT_N_TOKENS
#if HANDHELD
#define DEFAULT_N_TOKENS 10000
#else
#define DEFAULT_N_TOKENS 60000
#endif
#endif
#if (DEFAULT_N_TOKENS < 100 || DEFAULT_N_TOKENS >= (INT_MAX / 3))
#error DEFAULT_N_TOKENS out of range!
#endif
#define DIVISOR_SIZE min((DEFAULT_N_TOKENS / 2), 15000) /* a nice maximum divisor size */
/*
* All Mathomatic variables are referenced by the value in a C long int variable.
* The actual name string is stored separately.
*/
#define MAX_VAR_NAMES 8000 /* maximum number of variable names, keep this under (VAR_MASK - VAR_OFFSET) */
#define MAX_VAR_LEN 100 /* maximum number of characters in variable names */
#define MAX_VARS min(DEFAULT_N_TOKENS / 4, 1000) /* maximum number of unique variables handled in each equation */
#define VAR_OFFSET 'A' /* makes space for predefined variables */
#define VAR_MASK 0x3fffL /* mask for bits containing a reference to the variable name */
#define VAR_SHIFT 14 /* number of bits set in VAR_MASK */
#define SUBSCRIPT_MASK 63 /* mask for variable subscript after shifting VAR_SHIFT */
#define MAX_SUBSCRIPT (SUBSCRIPT_MASK - 1) /* maximum variable subscript, currently only used for "sign" variables */
typedef char sign_array_type[MAX_SUBSCRIPT+2]; /* boolean array for generating unique "sign" variables */
typedef struct { /* qsort(3) data structure for sorting Mathomatic variables */
long v; /* Mathomatic variable */
int count; /* number of times the variable occurs */
} sort_type;
/* A list of supported output languages for the code command: */
enum language_list {
C = 1, /* or C++ */
JAVA = 2,
PYTHON = 3
};
/* Debugging macros: */
#if SILENT
#define list_esdebug(level, en) { ; } /* Display an equation space. */
#define list_tdebug(level) { ; } /* Display the temporary equation (e.g.: when solving). */
#define side_debug(level, p1, n1) { ; } /* Display any expression. */
#define debug_string(level, str) { ; } /* Display any ASCII string. */
#else
#define list_esdebug(level, en) list_debug(level, lhs[en], n_lhs[en], rhs[en], n_rhs[en])
#define list_tdebug(level) list_debug(level, tlhs, n_tlhs, trhs, n_trhs)
#define side_debug(level, p1, n1) list_debug(level, p1, n1, NULL, 0)
#define debug_string(level, str) { if (debug_level >= (level)) fprintf(gfp, "%s\n", str); }
#endif
/* The correct ways to determine if equation number "en" (origin 0) contains an expression or equation. */
#define empty_equation_space(en) ((en) < 0 || (en) >= n_equations || n_lhs[(en)] <= 0)
#define equation_space_is_equation(en) ((en) >= 0 && (en) < n_equations && n_lhs[(en)] > 0 && n_rhs[(en)] > 0)
/*
* The following are macros for displaying help text.
* When used properly, they will allow nicer looking wrap-around on all help text.
* If NOT80COLUMNS is 1, paragraphs will all be one long line.
* This is helpful when the output device has less than 80 text character columns.
*/
#if NOT80COLUMNS
#define SP(str) fprintf(gfp, "%s ", str) /* display part of a paragraph, separated with spaces (Space Paragraph) */
#define EP(str) fprintf(gfp, "%s\n", str) /* display the end of a paragraph (End Paragraph) */
#else /* Otherwise the following only works nicely with 80 column or wider screens; */
/* all strings passed to it should be less than 80 columns if possible, so it doesn't wrap around. */
#define SP(str) fprintf(gfp, "%s\n", str)
#define EP(str) fprintf(gfp, "%s\n", str)
#endif

65
blt.h Normal file
View File

@ -0,0 +1,65 @@
/*
* blt(), also know as memmove(3), include file for Mathomatic.
*
* Copyright (C) 1987-2012 George Gesslein II.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
#if 1
#define blt(dest, src, cnt) memmove((dest), (src), (cnt)) /* memory copy function; must allow overlapping of src and dest */
#else
/* If no fast or working memmove(3) routine exists use this one. */
static inline char *
blt(dest, src, cnt)
char *dest;
const char *src;
int cnt;
{
char *tdest;
const char *tsrc;
int tcnt;
if (cnt <= 0) {
if (cnt == 0) {
return dest;
} else {
error_bug("blt() cnt < 0");
}
}
if (src == dest) {
return dest;
}
tdest = dest;
tsrc = src;
tcnt = cnt;
if (tdest > tsrc) {
tdest += tcnt;
tsrc += tcnt;
while (--tcnt >= 0)
*--tdest = *--tsrc;
} else {
while (--tcnt >= 0)
*tdest++ = *tsrc++;
}
return dest;
}
#endif

434
changes.txt Normal file
View File

@ -0,0 +1,434 @@
Version history of the Mathomatic computer algebra system
---------------------------------------------------------
This change log is entirely in chronological order;
the latest changes are at the end of this file.
Written and maintained by George Gesslein II.
This file is at "www.mathomatic.org/changes.txt".
-------------------------------------------------
Mathomatic version 15.8.5 released Friday 05/25/12.
CHANGES MADE TO MATHOMATIC 15.8.5 TO BRING IT UP TO THE NEXT VERSION:
Code, documentation, and user interface improvements, corrections,
and cleanup. Fixed many possible bugs, some where the wrong level global
expression buffers were being used.
05/26/12 - Push command improved with better responses. Same functionality.
In the source code, tune-up variable integer_coefficients was
renamed to "factor_out_all_numeric_gcds", because Mathomatic always
tries to have integer coefficients this year, but it doesn't always
factor out all numeric GCDs unless factor_out_all_numeric_gcds
is true, or the factor command is used. The default is false,
for more orderly and revealing coefficients.
Of course, much of what Mathomatic does is
try to improve readability and simplicity.
There is no need to set this variable, just use the factor command.
05/27/12 - Removed C declarations for memmove(3), the defaults in
/usr/include/string.h are probably better and what's wanted in
every case. It would be very odd if this didn't work 100%.
05/28/12 - readline history file renamed to "~/.matho_history" from
"~/.mathomatic_history". File name was too long for CygWin.
Tested thoroughly compiling, installing, and running under
the latest CygWin. Works fine, except for rlwrap. "rlwrap -v"
returns with error, a successful return is how I test for its
existence.
Made output redirection work with the "list primes" command.
06/02/12 - Cleanup of Linux, Mac OS X, and Windows binary distributions.
The Windows binary distribution now includes m4 scripts, in case
CygWin is installed, allowing use of m4 Mathomatic in Windows.
Fixed MinGW version to not output two carriage returns at the
end of every line of list command output.
06/03/12 - If compiled with -DSHOW_RESOURCES, will give total CPU usage and
RSS size in the "version status" command. Requires OS support.
Some OSes will show even more information. Uses getrusage(2).
06/04/12 - Allow breaking out of user line-input requests with Control-C.
Still have to hit the Enter key, but the command will be aborted.
06/05/12 - Added "lib/example.c", the simplest example yet of Symbolic Math
Library usage. Compile with "compile.testmain" or practice
compiling it by hand.
The simplify command now returns the number of expressions
simplified, so you can tell if "simplify sign" worked.
The solve command can now require verification, by using the
"verifiable" option, instead of the "verify" option. This causes
unverifiable solves to return with failure, aborting any reads.
Fixed missing code in internal C function free_mem().
I don't think it was used by anyone. A call to free_mem() is
now made on exit, if Mathomatic is compiled with -DVALGRIND, to
check for memory leaks.
06/08/12 - Added polynomial factoring to GCD result of divide command.
It is always handy to know what the factors are of the GCD.
Allow comma (,) at the end of most input lines. A comma now
terminates an expression instead of giving an error. Allow
commas all over the place, where-ever logical, in any
Mathomatic command-line. They are used as separators,
more so than spaces.
06/09/12 - Cleaned up variables command to always allow the count parameter,
and to line up everything with 8 character wide tabs.
Added ability to place the definite integration bounds on the
integrate command-line, just like the nintegrate command.
Added titles to most help command pages.
06/10/12 - The "factor number" command works much nicer now, and allows comma
separators and zero.
Developers should note that to remain the same as past versions,
HTML mode needs to be "set html all" to output HTML at all times
in both the application and the symbolic math library, even when
redirecting output. Now setting all HTML mode with
"make pdfsheet". "set html" only outputs HTML code to standard
output.
06/13/12 - Added warning in "misc/known_bugs.txt" about LLVM/Clang optimizer
failure when compiling Mathomatic with LLVM/Clang instead of gcc.
If you enable any optimization at all, entering (32^.5) and the
like will hang Mathomatic, putting it in an endless loop.
So when compiling Mathomatic with LLVM/Clang, always disable
optimization with "-O0", so that it will then run and pass
all of the tests in 1 second and not be infinitely slower.
Mathomatic will hang during "make test"
if compiled with optimization enabled using LLVM. Mathomatic is
not noticeably slower when compiled without any optimization,
because everything is memmove(3)s and floating point arithmetic.
06/15/12 - Added repeat option to replace command. A handy feature that
lets you try plugging different values into an equation. It
checks if the result is an identity, too.
06/18/12 - The version command now has a "status" option, which behaves
as before, displaying all version and status information.
The version command by itself now only displays the Mathomatic
version number. Running "mathomatic -v" is now a good way of
testing for the existence of Mathomatic on your system, only
outputting the version number to standard output and exiting
successfully.
06/19/12 - Removed the parenthesizing of variable names in all messages.
If the current expression is a non-equation, then prefixing or
suffixing an expression with "=" will add that expression as
the other equation side now, conveniently making it an equation
you can solve.
06/22/12 - Added equation number ranges option to tally command. Type
"tally -" to resume if the current equation hasn't changed. Type
"tally all" to add together all stored expressions as the starting
value. Specifying equation numbers or ranges will silently add
them, then prompt for the next things to add. The average option
now displays the number of entries (count) each time the average
is displayed. When you exit by typing an empty line, the current
total is saved in the next available equation space and made
current, so it can easily resume with "tally -". "-" by itself
always means the current equation.
gnuplot now works with MS-Windows better. Tried running a Windows
gnuplot test from scratch, without Cygwin, and it didn't work.
It should be mostly fixed now. So go ahead and try plotting
in Windows, after downloading and installing gnuplot. Please
complain if any problems.
Fixed a long-running problem with the plot command, by asking the
user questions, only if needed, so that gnuplot will not give an
error if you are multi-expression plotting.
06/23/12 - Moved load_rc() out of main.c so that the Mathomatic startup set
options file can be loaded by the library, if the developer wishes.
Changed a few things so that "set save" and "set no save" will work
if load_rc() is called beforehand.
06/25/12 - The simplify command has been fixed for optimal integer coefficient
factoring results and so "180*(sides-2)" simplification works
nicely, by keeping the result the same as the start by
factoring out rational constants greater than 1 (this is new),
along with less than 1,
if the coefficients remain or become integers.
Many things cleaned up and finished, like the official
documentation, the "code integer" command, and "examples/fact.c".
06/27/12 - Allow an ASCII string after the "set save" command, to save only
that string in ~/.mathomaticrc, so that string, which should be set
options, is for every Mathomatic session to start with.
For example, "set save bold color" will start out Mathomatic in
bold color mode every time. Enter "set no save" to remove.
"set save" by itself saves all of the current set options for every
future session.
Mathomatic version 16.0.0 released Friday 06/29/12.
CHANGES MADE TO MATHOMATIC 16.0.0 TO BRING IT UP TO THE NEXT VERSION:
07/06/12 - Confirmed successful compilation and testing with the
Tiny C compiler (tcc). Only needed to set the tcc linker
library directories to the current gcc library directories
to make it work (using the -L option).
Searched globally for the word "simply" and fixed many outdated
texts in the Mathomatic documentation and READMEs, deleting some
wrongly used "simply"s, too.
07/07/12 - Allow "set modulus_mode language", where language is C, Java,
Python, or positive.
07/08/12 - Now leaving the "UNIX" C preprocessor define alone,
when "HANDHELD" is defined. "UNIX" was previously
forced undefined.
07/11/12 - "make test", "make check", and ./t now display the actual
Mathomatic version number being tested.
matho-primes now has a -v (display version number) option,
like Mathomatic does.
Mathomatic now automatically clears out all old
numeric calculations if it runs out of equation spaces,
requiring no action from the user.
07/12/12 - The solve command never needs the "repeat solve" prefix anymore.
The repeat flag is always set for the solve command, so that
it will always do full simplifies when verifying.
Added quadratic formula derivation and proof to
"tests/quadratic.in".
07/17/12 - I came up with a swinging new and easy way to add, subtract,
multiply, divide, modular and integer divide,
and raise to the power of both sides of an equation by any
expression. To add x+1 to both sides of the current
equation, just type "+=x+1" at the main prompt. To divide both
sides by c^2, type "/=c^2". You can add stuff to non-equations
too, this way. Be sure and use the simplify command after this
if needed, because only a small amount of simplification is done
by default, just enough so you can see what is happening.
07/20/12 - Changed floating point to rational floating point conversion
routine (f_to_fraction()) to ignore converting anything with
over 15 digits, for greater accuracy.
This fixes some small accuracy bugs: "factor number 17!" now gives
an error instead of the wrong value.
07/21/12 - Integrate, Laplace, and Numerical Integrate commands now warn
when the current equation is not a properly solved equation.
Mathomatic version 16.0.1 released Sunday 07/22/12.
CHANGES MADE TO MATHOMATIC 16.0.1 TO BRING IT UP TO THE NEXT VERSION:
A nice cleanup and documenting of everything, while my mind still works.
07/23/12 - Enabled links in "manual.pdf" (the Mathomatic User Guide
and Command Reference), they were not working well before,
so I had disabled all links, but they work great now.
07/24/12 - Allow -a option ("set alternative") with sets alternative
color mode, useful in MS-Windows when using Cygwin with the
MinGW compiled version.
07/27/12 - Two bug fixes today:
Fixed using rlwrap under Cygwin and possibly other places,
when running rmath.
get_yes_no() question asker wasn't working in Cygwin or rmath.
Fixed to always ask the question, even if the input is not a TTY.
07/28/12 - Reading directories and empty files gives an error now.
07/30/12 - Split off changes.txt to changes.txt and changes_series_15.txt.
changes.txt and NEWS now contain only series 16 changes.
Added tests/batman_gnuplot_bug.in to prove there is a plotting bug
in gnuplot itself.
08/01/12 - Removed directive to use large font in the CSS for all Mathomatic
documentation. This is so it can be browsed easily with a mobile
device. The font size should be set by the user.
08/02/12 - A one-sided expression with an equals sign now only sets the
expression equal to zero if autocalc didn't work on it. In the
Symbolic Math Library, or without autocalc enabled, all is the
same. This makes it more likely purely numerical input is only
calculated, even when preceded or followed by an equals sign,
when autocalc is enabled. Reason for this change:
Why would you want to set a constant equal to 0?
Fixed a bunch more error reporting bugs coded into version 16.0.1
of Mathomatic to apply identical operations to both sides of an
equation. All fixed now. Points to the error correctly now, too.
08/04/12 - Major change to Symbolic Math Library. It now works exactly like
the application when it comes to purely numerical input,
approximating and displaying the result, however sign variables
are not expanded and the result is not 100% simplified,
so running "simplify sign" afterwards helps with that.
To revert to the old way, just turn off autocalc, or set
the numerical input equal to some normal variable; then there
will be no automatic approximation nor simplification.
You can tell when an input has been approximated because it
was numerical input, because it will always be preceded with
"answer =".
08/05/12 - m4/degrees.m4 copied with m4/functions.m4, when installing with
"make m4install", thanks to a suggestion by Reini Urban,
maintainer of the Cygwin version.
Mathomatic version 16.0.2 released Monday 08/06/12.
CHANGES MADE TO MATHOMATIC 16.0.2 TO BRING IT UP TO THE NEXT VERSION:
New command "set load" loads the current set options startup file again,
displaying the startup file as it reads it in.
If the file doesn't exist, or something is wrong, then an error message is
displayed and the set command returns with failure.
Accidently putting "load" in the startup file is now handled correctly.
08/09/12 - Allow "matho-primes all" and the command "list primes all" in
Mathomatic to continually output consecutive prime numbers.
08/12/12 - Fixed any rman errors in the makefile so they won't be ignored.
08/17/12 - rmath and matho no longer set the debug_level or modulus_mode,
so they can be set by the startup options file.
08/19/12 - Allow the repeat prefix on the approximate command, making it
approximate and simplify as much as the calculate command
does. Hopefully someday it will just give a temporary
result, too. Numerical input into the symbolic math library
now uses "repeat approximate" instead of just "approximate"
to approximate the user's input, so the result is the
same as the Mathomatic application's result.
Disallow the same warnings to be repeatedly displayed, if the
current warning is the same as the previous warning.
08/20/12 - Allow directory names as read command arguments, instructing
the read command to change the current directory to the specified
directory. Without any arguments, the read command now does an
"ls" command in Unix/Linux, and "dir" under MS-Windows, listing
the current directory contents. Running Mathomatic with a
directory name argument now conveniently changes directory to
that directory, then gives you the main prompt.
08/28/12 - Made "integer" type variables much more useful. For example,
the following now happens generally:
1-> i^(4*integer)
#1: i^(4*integer)
1-> simplify
#1: 1
1-> i^((4*integer) + 1)
#2: i^((4*integer) + 1)
2-> simplify
#2: i
2-> i^((4*integer) + 2)
#3: i^((4*integer) + 2)
3-> simplify
#3: -1
3-> i^((4*integer) + 3)
#4: i^((4*integer) + 3)
4-> simplify
#4: -1*i
08/29/12 - Displays "Calculating..." whenever autocalc is used now.
08/30/12 - Added ability to set the normal text color.
Still defaults to no color. Use "set color 0" to set the normal
text color to green, as it has been for many years in the past.
08/31/12 - Removed the "set preserve_surds" option, since the approximate
and calculate commands all take care of undoing that.
The code remains, however "set preserve_surds" is no longer
advertised. I have never used it.
Surds are preserved, for accuracy's sake, by default.
09/05/12 - "set" as a null set option works now, so no one will have any
trouble setting-up the set options startup file.
Mathomatic version 16.0.3 released Saturday 09/08/12.
CHANGES MADE TO MATHOMATIC 16.0.3 TO BRING IT UP TO THE NEXT VERSION:
09/09/12 - Allow use of editline library in Mathomatic, because somehow
use of GPL libraries in LGPL code is not allowed, and GNU readline
is GPL. I am so confused about this Debian bug#687063:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=687063
Based on the bug report's information sources,
it appears he is saying the truth about this license issue,
so I will have to upload new versions of
Mathomatic with editline instead of readline to Debian.
The only noticeable difference should be it doesn't save
the history between Mathomatic sessions.
I will comply with all that request it,
though most distributions do not include editline,
which has no major licensing restrictions. Readline is still
perfectly usable and good as before, you just have to link
it in yourself.
09/10/12 - Going to have to make a new release already, 2 days after the last
one, so I can upload this readline licensing fix to Debian by
linking with editline. There is no reason for anyone to upgrade
to version 16.0.4, unless you wish to link with editline instead
of readline. The proper code has been added. All you have to do
is have the editline libraries loaded on your system,
and run "make EDITLINE=1" to compile and link Mathomatic with
editline.
Mathomatic version 16.0.4 released Monday 09/10/12.
CHANGES MADE TO MATHOMATIC 16.0.4 TO BRING IT UP TO THE NEXT VERSION:
09/17/12 - Corrected and improved "tests/finance.in" and the terminology used,
thanks to Wolfram Alpha.
09/20/12 - Fixed "./update" command (which updates "proto.h") to work without
the readline development headers and libraries installed.
09/23/12 - m4/gradians.m4 copied with m4/functions.m4, when installing with
"make m4install" into "/usr/local/share/mathomatic/m4/",
so gradian trig mode can be used by typing "rmath gradians.m4"
at the shell prompt, while in that directory.
The debug level was being set in degrees.m4
and gradians.m4; no longer.
09/25/12 - Mathomatic now always runs "set load" after "set save",
for the convenience of immediately loading the specified settings,
and for error checking.
From now on Mathomatic does not set the alarm nor hangup handlers,
because it crashes the entire shell window when readline
is compiled in and an alarm or hangup signal happens.
Works acceptably now that these signal handlers are not set,
it just quits when time is up, saying "Alarm clock";
The same thing happens for SIGHUP, except it just says "Hangup"
and quits. I am really not liking readline nor its license now.
SIGALRM and SIGHUP are no longer given handlers. The default
seems to be what has to be there with the current readline mess.
Overwriting the current signal handlers causes serious bugs,
but only for readline.
09/29/12 - Fixed "lib/compile.testmain" to work with the latest linker.
10/16/12 - Made all output methods respect "set columns", so
"display all >output.txt" will not always use infinite columns.
This goes for the Symbolic Math Library, too.
Mathomatic version 16.0.5 released Sunday 10/21/12.

1700
changes_series_15.txt Normal file

File diff suppressed because it is too large Load Diff

4789
cmds.c Normal file

File diff suppressed because it is too large Load Diff

54
compile.mingw Executable file
View File

@ -0,0 +1,54 @@
#!/bin/sh
# Shell script for creating the Windows 32-bit executables "mathomatic.exe" and Prime Number Tools.
# In Debian or its derivatives, install the MinGW cross-compiler package mingw32 (tested;
# run "sudo apt-get install mingw32"). MinGW doesn't recognize long longs or
# long doubles, and the 64-bit version doesn't appear to work yet.
#
# The 32-bit executables created here are very capable, work standalone or with Cygwin,
# and do not require readline or editline to recall and edit command-line history,
# this already works in the Windows console (cmd.exe and command.com).
#
# To compile everything with MinGW, just type:
# ./compile.mingw
# This file may require editing if you are not using Debian or a derivative distro.
#
# Abort on any errors:
set -e
# Define the C cross-compiler and flags we are using here:
export CC=i586-mingw32msvc-cc
export CFLAGS="-O3 -Wall -DMINGW -DWIN32_CONSOLE_COLORS -DBOLD_COLOR $CFLAGS"
echo Compiling Windows 32-bit Mathomatic...
make clean
cd icons
i586-mingw32msvc-windres icon.rc icon.o
cd ..
AOUT=mathomatic.exe MATHOMATIC_OBJECTS="icons/icon.o" make -j
make clean
echo
echo Compiling the 32-bit Prime Number Tools...
cd primes
make flush
CFLAGS="-DUSE_DOUBLES $CFLAGS" make -j
make clean
echo
mv matho-primes matho-primes.exe
mv matho-pascal matho-pascal.exe
mv matho-sumsq matho-sumsq.exe
echo Prime Number Tools executables had .exe appended to the filenames.
cd ..
exit 0 # 64-bits isn't completely supported by MinGW yet.
export CC=amd64-mingw32msvc-cc
echo Compiling Windows 64-bit Mathomatic...
make clean
cd icons
amd64-mingw32msvc-windres icon.rc icon.o
cd ..
AOUT=mathomatic64.exe MATHOMATIC_OBJECTS="icons/icon.o" make -j
make clean

13
compile.secure Executable file
View File

@ -0,0 +1,13 @@
#!/bin/sh
# Shell script for creating the executable "mathomatic_secure",
# which lacks the code for file I/O and shelling out.
# The result can safely be used as an application on open public servers.
# The Mathomatic run-time option -s4 performs exactly the same function,
# so this script that makes a separate executable is no longer necessary.
# You will need to install the libeditline-dev package to run this.
echo Compiling Secure Mathomatic...
set -v
gcc -O3 -Wall -Wshadow -Wno-char-subscripts -fexceptions $CFLAGS $CPPFLAGS -DEDITLINE -DUNIX -DVERSION=\"`cat VERSION`\" -DSECURE -DTIMEOUT_SECONDS=3600 $LDFLAGS *.c -lm -leditline $LDLIBS -o mathomatic_secure && echo ./mathomatic_secure created.
make clean # for any subsequent makes

457
complex.c Normal file
View File

@ -0,0 +1,457 @@
/*
* Floating point complex number routines specifically for Mathomatic.
*
* Copyright (C) 1987-2012 George Gesslein II.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
#include "includes.h"
/*
* Convert doubles x and y from rectangular coordinates to polar coordinates.
*
* The amplitude is stored in *radiusp and the angle in radians is stored in *thetap.
*/
void
rect_to_polar(x, y, radiusp, thetap)
double x, y, *radiusp, *thetap;
{
*radiusp = sqrt(x * x + y * y);
*thetap = atan2(y, x);
}
/*
* The roots command.
*/
int
roots_cmd(cp)
char *cp;
{
#define MAX_ROOT 10000.0 /* Root limit needed because more roots become more inaccurate and take longer to check. */
complexs c, c2;
#if !SILENT
complexs check;
double d;
#endif
double k, root, radius, theta, radius_root = 0.0;
char buf[MAX_CMD_LEN];
do_repeat:
if (*cp == '\0') {
my_strlcpy(prompt_str, _("Enter root (positive integer): "), sizeof(prompt_str));
if ((cp = get_string(buf, sizeof(buf))) == NULL)
return false;
}
root = strtod(cp, &cp);
if ((*cp && *cp != ',' && !isspace(*cp)) || !isfinite(root) || root < 0.0 || root > MAX_ROOT || fmod(root, 1.0) != 0.0) {
error(_("Root invalid or out of range."));
printf(_("Root must be a positive integer less than or equal to %.0f.\n"), MAX_ROOT);
return false;
}
cp = skip_comma_space(cp);
if (*cp == '\0') {
my_strlcpy(prompt_str, _("Enter real part (X): "), sizeof(prompt_str));
if ((cp = get_string(buf, sizeof(buf))) == NULL)
return false;
}
c.re = strtod(cp, &cp);
if (*cp && *cp != ',' && !isspace(*cp)) {
error(_("Number expected."));
return false;
}
cp = skip_comma_space(cp);
if (*cp == '\0') {
my_strlcpy(prompt_str, _("Enter imaginary part (Y): "), sizeof(prompt_str));
if ((cp = get_string(buf, sizeof(buf))) == NULL)
return false;
}
c.im = strtod(cp, &cp);
if (*cp) {
error(_("Number expected."));
return false;
}
if (c.re == 0.0 && c.im == 0.0) {
return repeat_flag;
}
/* convert to polar coordinates */
errno = 0;
rect_to_polar(c.re, c.im, &radius, &theta);
if (root) {
radius_root = pow(radius, 1.0 / root);
}
check_err();
fprintf(gfp, _("\nThe polar coordinates are:\n%.*g amplitude and\n%.*g radians (%.*g degrees).\n\n"),
precision, radius, precision, theta, precision, theta * 180.0 / M_PI);
if (root) {
if (c.im == 0.0) {
fprintf(gfp, _("The %.12g roots of (%.12g)^(1/%.12g) are:\n\n"), root, c.re, root);
} else {
fprintf(gfp, _("The %.12g roots of (%.12g%+.12g*i)^(1/%.12g) are:\n\n"), root, c.re, c.im, root);
}
for (k = 0.0; k < root; k += 1.0) {
/* add constants to theta and convert back to rectangular coordinates */
c2.re = radius_root * cos((theta + 2.0 * k * M_PI) / root);
c2.im = radius_root * sin((theta + 2.0 * k * M_PI) / root);
complex_fixup(&c2);
if (c2.re || c2.im == 0.0) {
fprintf(gfp, "%.12g ", c2.re);
}
if (c2.im) {
fprintf(gfp, "%+.12g*i", c2.im);
}
fprintf(gfp, "\n");
#if !SILENT
if (debug_level <= 0) {
continue;
}
check = c2;
for (d = 1.0; d < root; d += 1.0) {
check = complex_mult(check, c2);
}
complex_fixup(&check);
printf(_("Inverse check:"));
if (check.re || check.im == 0.0) {
printf(" %.10g", check.re);
}
if (check.im) {
printf(" %+.10g*i", check.im);
}
printf("\n\n");
#endif
}
}
if (repeat_flag)
goto do_repeat;
return true;
}
/*
* Approximate roots of complex numbers in an equation side:
* (complex^real) and (real^complex) and (complex^complex) all result in a complex number.
* This only gives one root, even when there may be many roots.
* Works best when the equation side has been approximated before this.
*
* Return true if the equation side was modified.
*/
int
complex_root_simp(equation, np)
token_type *equation; /* equation side pointer */
int *np; /* pointer to length of equation side */
{
int i, j;
int level;
int len;
complexs c, p, r;
int modified = false;
start_over:
for (i = 1; i < *np; i += 2) {
if (equation[i].token.operatr != POWER)
continue;
level = equation[i].level;
for (j = i + 2; j < *np && equation[j].level >= level; j += 2)
;
len = j - (i + 1);
if (!parse_complex(&equation[i+1], len, &p))
continue;
for (j = i - 1; j >= 0 && equation[j].level >= level; j--)
;
j++;
if (!parse_complex(&equation[j], i - j, &c))
continue;
if (c.im == 0.0 && p.im == 0.0)
continue;
i += len + 1;
r = complex_pow(c, p);
#if 0
printf("(%.14g+%.14gi)^(%.14g+%.14gi) = %.14g+%.14gi\n", c.re, c.im, p.re, p.im, r.re, r.im);
#endif
if (*np + 5 - (i - j) > n_tokens) {
error_huge();
}
if ((j + 5) != i) {
blt(&equation[j+5], &equation[i], (*np - i) * sizeof(token_type));
*np += 5 - (i - j);
}
equation[j].level = level;
equation[j].kind = CONSTANT;
equation[j].token.constant = r.re;
j++;
equation[j].level = level;
equation[j].kind = OPERATOR;
equation[j].token.operatr = PLUS;
j++;
level++;
equation[j].level = level;
equation[j].kind = CONSTANT;
equation[j].token.constant = r.im;
j++;
equation[j].level = level;
equation[j].kind = OPERATOR;
equation[j].token.operatr = TIMES;
j++;
equation[j].level = level;
equation[j].kind = VARIABLE;
equation[j].token.variable = IMAGINARY;
modified = true;
goto start_over;
}
if (modified) {
debug_string(1, _("Complex number roots approximated."));
}
return modified;
}
/*
* Approximate all roots of complex numbers in an equation side.
*
* Return true if anything was approximated.
*/
int
approximate_complex_roots(equation, np)
token_type *equation; /* equation side pointer */
int *np; /* pointer to length of equation side */
{
int rv = false;
for (;;) {
elim_loop(equation, np);
if (!complex_root_simp(equation, np))
break;
rv = true;
}
return rv;
}
/*
* Get a constant, if the passed expression evaluates to a constant.
* This should not be called from low level routines.
*
* Return true if successful, with the floating point constant returned in *dp.
*/
int
get_constant(p1, n, dp)
token_type *p1; /* expression pointer */
int n; /* length of expression */
double *dp; /* pointer to returned double */
{
int i, j;
int level;
double d1, d2;
int prev_approx_flag;
#if DEBUG
if (n < 1 || (n & 1) != 1) {
error_bug("Call to get_constant() has invalid expression length.");
}
#endif
if (n == 1) {
switch (p1[0].kind) {
case CONSTANT:
*dp = p1[0].token.constant;
return true;
case VARIABLE:
if (var_is_const(p1[0].token.variable, dp)) {
return true;
}
break;
case OPERATOR:
break;
}
} else if (n >= 3) {
level = p1[1].level;
if (!get_constant(p1, 1, &d1))
return false;
for (i = 1; i < n; i = j) {
if (p1[i].kind != OPERATOR || p1[i].level > level) {
#if DEBUG
error_bug("Possible error in get_constant().");
#endif
return false;
}
level = p1[i].level;
for (j = i + 2; j < n && p1[j].level > level; j += 2)
;
if (!get_constant(&p1[i+1], j - (i + 1), &d2))
return false;
prev_approx_flag = approximate_roots;
approximate_roots = true;
if (calc(NULL, &d1, p1[i].token.operatr, d2)) {
approximate_roots = prev_approx_flag;
if (p1[i].token.operatr == POWER && !domain_check)
return false;
domain_check = false;
} else {
approximate_roots = prev_approx_flag;
domain_check = false;
return false;
}
}
*dp = d1;
return true;
}
return false;
}
/*
* Get the value of a constant complex number expression.
* Doesn't always work unless expression is approximated first
* with something like the approximate command.
* Functionality was greatly improved recently, making success more likely
* without approximating.
*
* If successful, return true with complex number in *cp.
*/
int
parse_complex(p1, n, cp)
token_type *p1; /* expression pointer */
int n; /* length of expression */
complexs *cp; /* pointer to returned complex number */
{
int j, k;
int imag_cnt = 0, times_cnt = 0;
complexs c, tmp;
int level, level2;
if (!exp_is_numeric(p1, n)) {
return false;
}
if (get_constant(p1, n, &c.re)) {
c.im = 0.0;
*cp = c;
return true;
}
if (found_var(p1, n, IMAGINARY) != 1)
return false;
level = min_level(p1, n);
c.re = 0.0;
c.im = 1.0;
j = n - 1;
do {
for (k = j - 1; k > 0 && p1[k].level > level; k -= 2)
;
if (k > 0) {
#if DEBUG
if (p1[k].level != level || p1[k].kind != OPERATOR) {
error_bug("Error in parse_complex().");
}
#endif
switch (p1[k].token.operatr) {
case MINUS:
case PLUS:
if (get_constant(&p1[k+1], j - k, &tmp.re)) {
if (p1[k].token.operatr == MINUS)
c.re -= tmp.re;
else
c.re += tmp.re;
j = k - 1;
}
}
} else
break;
} while (j < k);
for (; j >= 0; j--) {
switch (p1[j].kind) {
case CONSTANT:
break;
case VARIABLE:
if (var_is_const(p1[j].token.variable, NULL))
break;
if (p1[j].token.variable != IMAGINARY)
return false;
++imag_cnt;
break;
case OPERATOR:
level2 = p1[j].level;
switch (p1[j].token.operatr) {
case TIMES:
case DIVIDE:
if (++times_cnt > 1)
return false;
if (level2 > (level + 1) || p1[j+1].level != level2)
return false;
for (k = j; k > 0 && p1[k].level == level2; k -= 2) {
if (p1[k-1].level != level2)
return false;
if (!(p1[k+1].kind == VARIABLE && p1[k+1].token.variable == IMAGINARY)) {
if (get_constant(&p1[k+1], 1, &tmp.im)) {
if (p1[k].token.operatr == DIVIDE)
c.im /= tmp.im;
else
c.im *= tmp.im;
} else
return false;
} else if (p1[k].token.operatr == DIVIDE) {
c.im = -c.im;
}
if (p1[k-1].kind == VARIABLE && p1[k-1].token.variable == IMAGINARY) {
if (++imag_cnt > 1)
return false;
k -= 2;
if (k > 0 && p1[k].level == level2) {
if (p1[k-1].level != level2)
return false;
if (p1[k-1].kind == VARIABLE && p1[k-1].token.variable == IMAGINARY)
return false;
if (p1[k].token.operatr == DIVIDE)
c.im = -c.im;
} else
break;
}
}
if (!(p1[k+1].kind == VARIABLE && p1[k+1].token.variable == IMAGINARY)) {
if (get_constant(&p1[k+1], 1, &tmp.im)) {
c.im *= tmp.im;
} else
return false;
}
j = k + 1;
continue;
case MINUS:
if (imag_cnt) {
c.im = -c.im;
}
case PLUS:
if (level != level2)
return false;
if (get_constant(p1, j, &tmp.re)) {
c.re += tmp.re;
goto done;
}
return false;
}
default:
return false;
}
}
done:
if (imag_cnt != 1) {
#if DEBUG
error_bug("Imaginary count wrong in parse_complex().");
#else
return false;
#endif
}
*cp = c;
return true;
}

41
complex.h Normal file
View File

@ -0,0 +1,41 @@
/*
* Include file for the double precision floating point complex number
* arithmetic functions in "complex_lib.c".
*
* Copyright (C) 1987-2012 George Gesslein II.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
typedef struct complexs { /* complex number structure */
double re; /* real part */
double im; /* imaginary part */
} complexs;
/*
* Complex number arithmetic function prototypes
*/
int complex_fixup(complexs *ap);
complexs complex_add(complexs a, complexs b);
complexs complex_negate(complexs a);
complexs complex_mult(complexs a, complexs b);
complexs complex_div(complexs a, complexs b);
complexs complex_log(complexs a);
complexs complex_exp(complexs a);
complexs complex_pow(complexs a, complexs b);

167
complex_lib.c Normal file
View File

@ -0,0 +1,167 @@
/*
* A handy, tested, small, stand-alone, double precision floating point
* complex number arithmetic library for C.
* Just include "complex.h" if you use this.
*
* Copyright (C) 1987-2012 George Gesslein II.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
#include "complex.h"
#include <math.h>
#define true 1
#define false 0
#define epsilon 0.00000000000005 /* a good value for doubles */
/*
* Zero out relatively very small real or imaginary parts of a complex number,
* because they probably are a result of accumulated floating point inaccuracies.
*
* Return true if something was zeroed out.
*/
int
complex_fixup(ap)
complexs *ap; /* complex number pointer */
{
if (fabs(ap->re * epsilon) > fabs(ap->im)) {
ap->im = 0.0;
return true;
}
if (fabs(ap->im * epsilon) > fabs(ap->re)) {
ap->re = 0.0;
return true;
}
return false;
}
/*
* Add two complex numbers (a + b)
* and return the complex number result.
*
* Complex number subtraction (a - b) is done by
* complex_add(a, complex_negate(b)).
*/
complexs
complex_add(a, b)
complexs a, b;
{
a.re += b.re;
a.im += b.im;
return(a);
}
/*
* Negate a complex number (-a)
* and return the complex number result.
*/
complexs
complex_negate(a)
complexs a;
{
a.re = -a.re;
a.im = -a.im;
return(a);
}
/*
* Multiply two complex numbers (a * b)
* and return the complex number result.
*/
complexs
complex_mult(a, b)
complexs a, b;
{
complexs r;
r.re = a.re * b.re - a.im * b.im;
r.im = a.re * b.im + a.im * b.re;
return(r);
}
/*
* Divide two complex numbers (a / b)
* and return the complex number result.
*/
complexs
complex_div(a, b)
complexs a; /* dividend */
complexs b; /* divisor */
{
complexs r, num;
double denom;
b.im = -b.im;
num = complex_mult(a, b);
denom = b.re * b.re + b.im * b.im;
r.re = num.re / denom;
r.im = num.im / denom;
return r;
}
/*
* Take the natural logarithm of a complex number
* and return the complex number result.
*/
complexs
complex_log(a)
complexs a;
{
complexs r;
r.re = log(a.re * a.re + a.im * a.im) / 2.0;
r.im = atan2(a.im, a.re);
return(r);
}
/*
* Raise the natural number (e) to the power of a complex number (e^a)
* and return the complex number result.
*/
complexs
complex_exp(a)
complexs a;
{
complexs r;
double m;
m = exp(a.re);
r.re = m * cos(a.im);
r.im = m * sin(a.im);
return(r);
}
/*
* Raise complex number "a" to the power of complex number "b" (a^b)
* and return the complex number result.
*/
complexs
complex_pow(a, b)
complexs a, b;
{
complexs r;
r = complex_log(a);
r = complex_mult(r, b);
r = complex_exp(r);
complex_fixup(&r);
return(r);
}

893
diff.c Normal file
View File

@ -0,0 +1,893 @@
/*
* Mathomatic symbolic differentiation routines and related commands.
*
* Copyright (C) 1987-2012 George Gesslein II.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
#include "includes.h"
static int d_recurse(token_type *equation, int *np, int loc, int level, long v);
/*
* Compute the derivative of an equation side, with respect to variable "v",
* using the fast, rule-based transform method.
* This is done by recursively applying the proper rule of differentiation
* for each operator encountered.
*
* Return true if successful.
* The result must be simplified by the caller.
*/
int
differentiate(equation, np, v)
token_type *equation; /* pointer to source and destination equation side */
int *np; /* pointer to the length of the equation side */
long v; /* differentiation variable */
{
int i;
organize(equation, np);
/* First put every times and divide on a level by itself. */
for (i = 1; i < *np; i += 2) {
switch (equation[i].token.operatr) {
case TIMES:
case DIVIDE:
binary_parenthesize(equation, *np, i);
}
}
return d_recurse(equation, np, 0, 1, v);
}
/*
* Recursive differentiation routine.
*
* Symbolically differentiate expression in "equation"
* (which is a standard equation side) starting at "loc".
* The current level of parentheses is "level" and
* do the differentiation with respect to variable "v".
*
* Return true if successful.
* Return false if it is beyond this program's capabilities or an error was encountered.
*/
static int
d_recurse(equation, np, loc, level, v)
token_type *equation;
int *np, loc, level;
long v;
{
int i, j;
int n;
int op;
int oploc, endloc;
complexs c;
if (equation[loc].level < level) {
/* First differentiate if it is a single variable or constant. */
/* If it is the specified variable, change it to the constant 1, */
/* otherwise change it to the constant 0. */
if (equation[loc].kind == VARIABLE
&& ((v == MATCH_ANY && (equation[loc].token.variable & VAR_MASK) > SIGN)
|| equation[loc].token.variable == v)) {
equation[loc].kind = CONSTANT;
equation[loc].token.constant = 1.0;
} else {
equation[loc].kind = CONSTANT;
equation[loc].token.constant = 0.0;
}
return true;
}
for (op = 0, oploc = endloc = loc + 1; endloc < *np && equation[endloc].level >= level; endloc += 2) {
if (equation[endloc].level == level) {
switch (op) {
case 0:
case PLUS:
case MINUS:
break;
default:
/* Oops. More than one operator on the same level in this expression. */
error_bug("Internal error in d_recurse(): differentiating with unparenthesized operators is not allowed.");
return false;
}
op = equation[endloc].token.operatr;
oploc = endloc;
}
}
switch (op) {
case 0:
case PLUS:
case MINUS:
break;
case TIMES:
goto d_times;
case DIVIDE:
goto d_divide;
case POWER:
goto d_power;
default:
/* Differentiate an unsupported operator. */
/* This is possible if the expression doesn't contain the specified variable. */
/* In that case, the expression is replaced with "0", otherwise return false. */
for (i = loc; i < endloc; i += 2) {
if (equation[i].kind == VARIABLE
&& ((v == MATCH_ANY && (equation[i].token.variable & VAR_MASK) > SIGN)
|| equation[i].token.variable == v)) {
return false;
}
}
blt(&equation[loc+1], &equation[endloc], (*np - endloc) * sizeof(token_type));
*np -= (endloc - (loc + 1));
equation[loc].level = level;
equation[loc].kind = CONSTANT;
equation[loc].token.constant = 0.0;
return true;
}
/* Differentiate PLUS and MINUS operators. */
/* Use addition rule: d(u+v) = d(u) + d(v), */
/* where "d()" is the derivative function */
/* and "u" and "v" are expressions. */
for (i = loc; i < *np && equation[i].level >= level;) {
if (equation[i].kind != OPERATOR) {
if (!d_recurse(equation, np, i, level + 1, v))
return false;
i++;
for (; i < *np && equation[i].level > level; i += 2)
;
continue;
}
i++;
}
return true;
d_times:
/* Differentiate TIMES operator. */
/* Use product rule: d(u*v) = u*d(v) + v*d(u). */
if (*np + 1 + (endloc - loc) > n_tokens) {
error_huge();
}
for (i = loc; i < endloc; i++)
equation[i].level++;
blt(&equation[endloc+1], &equation[loc], (*np - loc) * sizeof(token_type));
*np += 1 + (endloc - loc);
equation[endloc].level = level;
equation[endloc].kind = OPERATOR;
equation[endloc].token.operatr = PLUS;
if (!d_recurse(equation, np, endloc + (oploc - loc) + 2, level + 2, v))
return false;
return(d_recurse(equation, np, loc, level + 2, v));
d_divide:
/* Differentiate DIVIDE operator. */
/* Use quotient rule: d(u/v) = (v*d(u) - u*d(v))/v^2. */
if (*np + 3 + (endloc - loc) + (endloc - oploc) > n_tokens) {
error_huge();
}
for (i = loc; i < endloc; i++)
equation[i].level += 2;
equation[oploc].token.operatr = TIMES;
j = 1 + (endloc - loc);
blt(&equation[endloc+1], &equation[loc], (*np - loc) * sizeof(token_type));
*np += j;
equation[endloc].level = level + 1;
equation[endloc].kind = OPERATOR;
equation[endloc].token.operatr = MINUS;
j += endloc;
blt(&equation[j+2+(endloc-oploc)], &equation[j], (*np - j) * sizeof(token_type));
*np += 2 + (endloc - oploc);
equation[j].level = level;
equation[j].kind = OPERATOR;
equation[j].token.operatr = DIVIDE;
blt(&equation[j+1], &equation[oploc+1], (endloc - (oploc + 1)) * sizeof(token_type));
j += endloc - oploc;
equation[j].level = level + 1;
equation[j].kind = OPERATOR;
equation[j].token.operatr = POWER;
j++;
equation[j].level = level + 1;
equation[j].kind = CONSTANT;
equation[j].token.constant = 2.0;
if (!d_recurse(equation, np, endloc + (oploc - loc) + 2, level + 3, v))
return false;
return(d_recurse(equation, np, loc, level + 3, v));
d_power:
/* Differentiate POWER operator. */
/* Since we don't have symbolic logarithms, do all we can without them. */
for (i = oploc; i < endloc; i++) {
if (equation[i].kind == VARIABLE
&& ((v == MATCH_ANY && (equation[i].token.variable & VAR_MASK) > SIGN)
|| equation[i].token.variable == v)) {
if (parse_complex(&equation[loc], oploc - loc, &c)) {
c = complex_log(c);
n = (endloc - oploc) + 6;
if (*np + n > n_tokens) {
error_huge();
}
blt(&equation[endloc+n], &equation[endloc], (*np - endloc) * sizeof(token_type));
*np += n;
n = endloc;
equation[n].level = level;
equation[n].kind = OPERATOR;
equation[n].token.operatr = TIMES;
n++;
equation[n].level = level + 1;
equation[n].kind = CONSTANT;
equation[n].token.constant = c.re;
n++;
equation[n].level = level + 1;
equation[n].kind = OPERATOR;
equation[n].token.operatr = PLUS;
n++;
equation[n].level = level + 2;
equation[n].kind = CONSTANT;
equation[n].token.constant = c.im;
n++;
equation[n].level = level + 2;
equation[n].kind = OPERATOR;
equation[n].token.operatr = TIMES;
n++;
equation[n].level = level + 2;
equation[n].kind = VARIABLE;
equation[n].token.variable = IMAGINARY;
n++;
equation[n].level = level;
equation[n].kind = OPERATOR;
equation[n].token.operatr = TIMES;
n++;
blt(&equation[n], &equation[oploc+1], (endloc - (oploc + 1)) * sizeof(token_type));
for (i = loc; i < endloc; i++) {
equation[i].level++;
}
return(d_recurse(equation, np, n, level + 1, v));
}
return false;
}
}
blt(scratch, &equation[oploc+1], (endloc - (oploc + 1)) * sizeof(token_type));
n = endloc - (oploc + 1);
scratch[n].level = level;
scratch[n].kind = OPERATOR;
scratch[n].token.operatr = TIMES;
n++;
if (n + (endloc - loc) + 2 > n_tokens) {
error_huge();
}
blt(&scratch[n], &equation[loc], (endloc - loc) * sizeof(token_type));
i = n;
n += oploc + 1 - loc;
for (; i < n; i++)
scratch[i].level++;
n += endloc - (oploc + 1);
for (; i < n; i++)
scratch[i].level += 2;
scratch[n].level = level + 2;
scratch[n].kind = OPERATOR;
scratch[n].token.operatr = MINUS;
n++;
scratch[n].level = level + 2;
scratch[n].kind = CONSTANT;
scratch[n].token.constant = 1.0;
n++;
if (n + (oploc - loc) + 1 > n_tokens) {
error_huge();
}
scratch[n].level = level;
scratch[n].kind = OPERATOR;
scratch[n].token.operatr = TIMES;
n++;
j = n;
blt(&scratch[n], &equation[loc], (oploc - loc) * sizeof(token_type));
n += oploc - loc;
if (*np - (endloc - loc) + n > n_tokens) {
error_huge();
}
blt(&equation[loc+n], &equation[endloc], (*np - endloc) * sizeof(token_type));
*np += loc + n - endloc;
blt(&equation[loc], scratch, n * sizeof(token_type));
return(d_recurse(equation, np, loc + j, level + 1, v));
}
/*
* The derivative command.
*/
int
derivative_cmd(cp)
char *cp;
{
int i, len;
long v = 0; /* Mathomatic variable */
long l1, order = 1;
token_type *source, *dest;
int n1, *nps, *np;
int simplify_flag = true, solved;
if (current_not_defined()) {
return false;
}
solved = solved_equation(cur_equation);
if (strcmp_tospace(cp, "nosimplify") == 0) {
simplify_flag = false;
cp = skip_param(cp);
}
i = next_espace();
if (n_rhs[cur_equation]) {
if (!solved) {
warning(_("Not a solved equation. Only the RHS will be differentiated."));
}
source = rhs[cur_equation];
nps = &n_rhs[cur_equation];
dest = rhs[i];
np = &n_rhs[i];
} else {
source = lhs[cur_equation];
nps = &n_lhs[cur_equation];
dest = lhs[i];
np = &n_lhs[i];
}
/* parse the command line or prompt: */
if (*cp) {
if (is_all(cp)) {
cp = skip_param(cp);
v = MATCH_ANY;
} else {
if (isvarchar(*cp)) {
cp = parse_var2(&v, cp);
if (cp == NULL) {
return false;
}
}
}
if (*cp) {
order = decstrtol(cp, &cp);
}
if (order <= 0) {
error(_("The order must be a positive integer."));
return false;
}
if (extra_characters(cp))
return false;
}
if (no_vars(source, *nps, &v)) {
warning(_("Current expression contains no variables; the derivative will be zero."));
} else {
if (v == 0) {
if (!prompt_var(&v)) {
return false;
}
}
if (v && v != MATCH_ANY && !found_var(source, *nps, v)) {
warning(_("Specified variable not found; the derivative will be zero."));
}
}
if (v == 0) {
error(_("No differentiation variable specified."));
return false;
}
#if !SILENT
list_var(v, 0);
if (n_rhs[cur_equation]) {
fprintf(gfp, _("Differentiating the RHS with respect to %s"), var_str);
} else {
fprintf(gfp, _("Differentiating with respect to %s"), var_str);
}
if (order != 1) {
fprintf(gfp, _(" %ld times"), order);
}
if (simplify_flag) {
fprintf(gfp, _(" and simplifying"));
} else {
fprintf(gfp, _(" and not simplifying"));
}
fprintf(gfp, "...\n");
#endif
blt(dest, source, *nps * sizeof(token_type));
n1 = *nps;
/* do the actual differentiating and simplifying: */
for (l1 = 0; l1 < order; l1++) {
if (order != 1) {
if (n1 == 1 && dest[0].kind == CONSTANT && dest[0].token.constant == 0.0) {
fprintf(gfp, _("0 reached after %ld derivatives taken.\n"), l1);
order = l1;
break;
}
}
if (!differentiate(dest, &n1, v)) {
error(_("Differentiation failed."));
return false;
}
if (simplify_flag) {
simpa_repeat_side(dest, &n1, true, false);
} else {
elim_loop(dest, &n1);
}
}
*np = n1;
if (n_rhs[cur_equation]) {
blt(lhs[i], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type));
n_lhs[i] = n_lhs[cur_equation];
if (solved && isvarchar('\'')) {
len = list_var(lhs[i][0].token.variable, 0);
for (l1 = 0; l1 < order && len < (MAX_VAR_LEN - 1); l1++) {
var_str[len++] = '\'';
}
var_str[len] = '\0';
if (l1 == order) {
parse_var(&lhs[i][0].token.variable, var_str);
}
}
}
cur_equation = i;
return return_result(cur_equation);
}
/*
* The extrema command.
*/
int
extrema_cmd(cp)
char *cp;
{
int i;
long v = 0; /* Mathomatic variable */
long l1, order = 1;
token_type want;
token_type *source;
int n;
if (current_not_defined()) {
return false;
}
i = next_espace();
if (n_rhs[cur_equation]) {
if (!solved_equation(cur_equation)) {
error(_("The current equation is not solved for a variable."));
return false;
}
source = rhs[cur_equation];
n = n_rhs[cur_equation];
} else {
source = lhs[cur_equation];
n = n_lhs[cur_equation];
}
if (*cp) {
if (isvarchar(*cp)) {
cp = parse_var2(&v, cp);
if (cp == NULL) {
return false;
}
}
if (*cp) {
order = decstrtol(cp, &cp);
}
if (order <= 0) {
error(_("The order must be a positive integer."));
return false;
}
if (extra_characters(cp))
return false;
}
show_usage = false;
if (no_vars(source, n, &v)) {
error(_("Current expression contains no variables."));
return false;
}
if (v == 0) {
if (!prompt_var(&v)) {
return false;
}
}
if (!found_var(source, n, v)) {
error(_("Specified variable not found; the derivative would be zero."));
return false;
}
blt(rhs[i], source, n * sizeof(token_type));
/* take derivatives with respect to the specified variable and simplify: */
for (l1 = 0; l1 < order; l1++) {
if (!differentiate(rhs[i], &n, v)) {
error(_("Differentiation failed."));
return false;
}
simpa_repeat_side(rhs[i], &n, true, false);
}
if (!found_var(rhs[i], n, v)) {
error(_("There are no solutions."));
return false;
}
n_rhs[i] = n;
/* set equal to zero: */
n_lhs[i] = 1;
lhs[i][0] = zero_token;
cur_equation = i;
/* lastly, solve for the specified variable and simplify: */
want.level = 1;
want.kind = VARIABLE;
want.token.variable = v;
if (solve_sub(&want, 1, lhs[i], &n_lhs[i], rhs[i], &n_rhs[i]) <= 0) {
error(_("Solve failed."));
return false;
}
simpa_repeat_side(rhs[i], &n_rhs[i], false, false);
return return_result(cur_equation);
}
/*
* The taylor command.
*/
int
taylor_cmd(cp)
char *cp;
{
long v = 0; /* Mathomatic variable */
int i, j, k, i1;
int level;
long l1, n, order = -1L;
double d;
char *cp_start, *cp1 = NULL, buf[MAX_CMD_LEN];
int our;
int our_nlhs, our_nrhs;
token_type *ep, *source, *dest;
int n1, *nps, *np;
int simplify_flag = true;
cp_start = cp;
if (current_not_defined()) {
return false;
}
if (strcmp_tospace(cp, "nosimplify") == 0) {
simplify_flag = false;
cp = skip_param(cp);
}
i = next_espace();
blt(lhs[i], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type));
n_lhs[i] = n_lhs[cur_equation];
n_rhs[i] = 0;
our = alloc_next_espace();
n_lhs[i] = 0;
if (our < 0) {
error(_("Out of free equation spaces."));
show_usage = false;
return false;
}
if (n_rhs[cur_equation]) {
source = rhs[cur_equation];
nps = &n_rhs[cur_equation];
dest = rhs[i];
np = &n_rhs[i];
} else {
source = lhs[cur_equation];
nps = &n_lhs[cur_equation];
dest = lhs[i];
np = &n_lhs[i];
}
if (*cp && isvarchar(*cp)) {
cp = parse_var2(&v, cp);
if (cp == NULL) {
return false;
}
}
if (*cp) {
order = decstrtol(cp, &cp1);
if (cp1 != skip_param(cp) || order < 0) {
error(_("Positive integer required for order."));
return false;
}
cp = cp1;
}
show_usage = false;
no_vars(source, *nps, &v);
if (v == 0) {
if (!prompt_var(&v)) {
return false;
}
}
if (!found_var(source, *nps, v)) {
warning(_("Specified differentiation variable not found; the derivative will be 0."));
}
blt(rhs[our], source, *nps * sizeof(token_type));
our_nrhs = *nps;
/* Simplify and take the first derivative: */
uf_simp(rhs[our], &our_nrhs);
if (!differentiate(rhs[our], &our_nrhs, v)) {
error(_("Differentiation failed."));
return false;
}
if (*cp) {
input_column += (cp - cp_start);
cp = parse_expr(lhs[our], &our_nlhs, cp, true);
if (cp == NULL || extra_characters(cp) || our_nlhs <= 0) {
show_usage = true;
return false;
}
} else {
#if !SILENT
list_var(v, 0);
printf(_("Taylor series expansion around %s = point.\n"), var_str);
#endif
my_strlcpy(prompt_str, _("Enter point (an expression; usually 0): "), sizeof(prompt_str));
if (!get_expr(lhs[our], &our_nlhs)) {
return false;
}
}
if (order < 0) {
my_strlcpy(prompt_str, _("Enter order (number of derivatives to take): "), sizeof(prompt_str));
if ((cp1 = get_string(buf, sizeof(buf))) == NULL)
return false;
if (*cp1) {
cp = NULL;
order = decstrtol(cp1, &cp);
if (cp == NULL || *cp || order < 0) {
error(_("Positive integer required for order."));
return false;
}
} else {
order = LONG_MAX - 1;
#if !SILENT
printf(_("Derivatives will be taken until they reach zero...\n"));
#endif
}
}
#if !SILENT
fprintf(gfp, _("Taylor series"));
if (n_rhs[cur_equation]) {
fprintf(gfp, _(" of the RHS"));
}
list_var(v, 0);
fprintf(gfp, _(" with respect to %s"), var_str);
if (simplify_flag) {
fprintf(gfp, _(", simplified"));
} else {
fprintf(gfp, _(", not simplified"));
}
fprintf(gfp, "...\n");
#endif
n = 0;
i1 = 0;
blt(dest, source, *nps * sizeof(token_type));
n1 = *nps;
loop_again:
for (k = i1; k < n1; k += 2) {
if (dest[k].kind == VARIABLE && dest[k].token.variable == v) {
level = dest[k].level;
if ((n1 + our_nlhs - 1) > n_tokens)
error_huge();
blt(&dest[k+our_nlhs], &dest[k+1], (n1 - (k + 1)) * sizeof(token_type));
n1 += our_nlhs - 1;
j = k;
blt(&dest[k], lhs[our], our_nlhs * sizeof(token_type));
k += our_nlhs;
for (; j < k; j++)
dest[j].level += level;
k--;
}
}
if ((n1 + our_nlhs + 7) > n_tokens)
error_huge();
for (k = i1; k < n1; k++)
dest[k].level++;
ep = &dest[n1];
ep->level = 1;
ep->kind = OPERATOR;
ep->token.operatr = TIMES;
ep++;
ep->level = 3;
ep->kind = VARIABLE;
ep->token.variable = v;
ep++;
ep->level = 3;
ep->kind = OPERATOR;
ep->token.operatr = MINUS;
n1 += 3;
j = n1;
blt(&dest[n1], lhs[our], our_nlhs * sizeof(token_type));
n1 += our_nlhs;
for (; j < n1; j++)
dest[j].level += 3;
ep = &dest[n1];
ep->level = 2;
ep->kind = OPERATOR;
ep->token.operatr = POWER;
ep++;
ep->level = 2;
ep->kind = CONSTANT;
ep->token.constant = n;
ep++;
ep->level = 1;
ep->kind = OPERATOR;
ep->token.operatr = DIVIDE;
ep++;
for (d = 1.0, l1 = 2; l1 <= n; l1++)
d *= l1;
ep->level = 1;
ep->kind = CONSTANT;
ep->token.constant = d;
n1 += 4;
for (; i1 < n1; i1++)
dest[i1].level++;
if (simplify_flag) {
uf_simp(dest, &n1);
}
side_debug(1, dest, n1);
if (exp_contains_infinity(dest, n1)) {
error(_("Result invalid because it contains infinity or NaN."));
return false;
}
if (n < order) {
if (n > 0) {
if (!differentiate(rhs[our], &our_nrhs, v)) {
error(_("Differentiation failed."));
return false;
}
}
/* symb_flag = symblify; */
simpa_repeat_side(rhs[our], &our_nrhs, true, false /* was true */);
/* symb_flag = false; */
if (our_nrhs != 1 || rhs[our][0].kind != CONSTANT || rhs[our][0].token.constant != 0.0) {
i1 = n1;
if ((i1 + 1 + our_nrhs) > n_tokens)
error_huge();
for (j = 0; j < i1; j++)
dest[j].level++;
dest[i1].level = 1;
dest[i1].kind = OPERATOR;
dest[i1].token.operatr = PLUS;
i1++;
blt(&dest[i1], rhs[our], our_nrhs * sizeof(token_type));
n1 = i1 + our_nrhs;
n++;
goto loop_again;
}
}
#if !SILENT
fprintf(gfp, _("%ld non-zero derivative%s applied.\n"), n, (n == 1) ? "" : "s");
#endif
if (n_rhs[cur_equation]) {
n_lhs[i] = n_lhs[cur_equation];
}
*np = n1;
cur_equation = i;
return return_result(cur_equation);
}
/*
* The limit command.
*/
int
limit_cmd(cp)
char *cp;
{
int i;
long v = 0; /* Mathomatic variable */
token_type solved_v, want;
char *cp_start;
cp_start = cp;
if (current_not_defined()) {
return false;
}
i = next_espace();
if (n_rhs[cur_equation] == 0) {
/* make expression into an equation: */
blt(rhs[cur_equation], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type));
n_rhs[cur_equation] = n_lhs[cur_equation];
n_lhs[cur_equation] = 1;
lhs[cur_equation][0].level = 1;
lhs[cur_equation][0].kind = VARIABLE;
parse_var(&lhs[cur_equation][0].token.variable, "limit");
}
if (!solved_equation(cur_equation)) {
error(_("The current equation is not solved for a variable."));
return false;
}
solved_v = lhs[cur_equation][0];
/* parse the command line or prompt: */
if (*cp) {
cp = parse_var2(&v, cp);
if (cp == NULL) {
return false;
}
}
show_usage = false;
if (no_vars(rhs[cur_equation], n_rhs[cur_equation], &v)) {
warning(_("Current expression contains no variables; that is the answer."));
return return_result(cur_equation);
}
if (v == 0) {
if (!prompt_var(&v)) {
return false;
}
}
if (!found_var(rhs[cur_equation], n_rhs[cur_equation], v)) {
warning(_("Limit variable not found; answer is original expression."));
return return_result(cur_equation);
}
if (*cp == '=') {
cp = skip_space(cp + 1);
}
if (*cp) {
input_column += (cp - cp_start);
cp = parse_expr(tes, &n_tes, cp, true);
if (cp == NULL || extra_characters(cp) || n_tes <= 0) {
show_usage = true;
return false;
}
} else {
list_var(v, 0);
snprintf(prompt_str, sizeof(prompt_str), _("as %s goes to: "), var_str);
if (!get_expr(tes, &n_tes)) {
return false;
}
}
simp_loop(tes, &n_tes);
#if !SILENT
list_var(v, 0);
fprintf(gfp, _("Taking the limit as %s goes to "), var_str);
list_proc(tes, n_tes, false);
fprintf(gfp, "\n");
#endif
/* copy the current equation to a new equation space, then simplify and work on the copy: */
copy_espace(cur_equation, i);
simpa_side(rhs[i], &n_rhs[i], false, false);
/* see if the limit expression is positive infinity: */
if (n_tes == 1 && tes[0].kind == CONSTANT && tes[0].token.constant == INFINITY) {
/* To take the limit to positive infinity, */
/* replace infinity with zero and replace the limit variable with its reciprocal: */
n_tes = 1;
tes[0] = zero_token;
tlhs[0] = one_token;
tlhs[1].level = 1;
tlhs[1].kind = OPERATOR;
tlhs[1].token.operatr = DIVIDE;
tlhs[2].level = 1;
tlhs[2].kind = VARIABLE;
tlhs[2].token.variable = v;
n_tlhs = 3;
subst_var_with_exp(rhs[i], &n_rhs[i], tlhs, n_tlhs, v);
}
/* General limit taking, solve for the limit variable: */
debug_string(0, _("Solving..."));
want.level = 1;
want.kind = VARIABLE;
want.token.variable = v;
if (solve_sub(&want, 1, lhs[i], &n_lhs[i], rhs[i], &n_rhs[i]) <= 0) {
error(_("Can't take the limit because solve failed."));
return false;
}
/* replace the limit variable (LHS) with the limit expression: */
blt(lhs[i], tes, n_tes * sizeof(token_type));
n_lhs[i] = n_tes;
/* simplify the RHS: */
symb_flag = symblify;
simpa_side(rhs[i], &n_rhs[i], false, false);
symb_flag = false;
if (exp_contains_nan(rhs[i], n_rhs[i])) {
error(_("Unable to take limit; result contains NaN (Not a Number)."));
return false;
}
/* solve back for the original variable: */
if (solve_sub(&solved_v, 1, lhs[i], &n_lhs[i], rhs[i], &n_rhs[i]) <= 0) {
error(_("Can't take the limit because solve failed."));
return false;
}
/* simplify before returning the result: */
simpa_side(rhs[i], &n_rhs[i], false, false);
if (exp_contains_nan(rhs[i], n_rhs[i])) {
error(_("Unable to take limit; result contains NaN (Not a Number)."));
return false;
}
return return_result(i);
}

16
doc/README.txt Normal file
View File

@ -0,0 +1,16 @@
This directory contains the complete Mathomatic user documentation in HTML.
Everything in this documentation directory is copyrighted and licensed under
the GNU Free Documentation License version 1.3. The full text of this license
is contained in file "fdl-1.3-standalone.html".
To read or print the Mathomatic user documentation, point your web browser to
the file "index.html". If the PDF documentation was created, it is in the
file "../manual.pdf". This PDF document is made by the htmldoc program by
typing "make pdf" in the parent directory.
When copying the Mathomatic documentation, please copy this entire directory,
not just selected HTML files from it.
To view online the most recent documentation, visit
http://mathomatic.org/math/doc/ with your web browser.

2615
doc/am.html Normal file

File diff suppressed because it is too large Load Diff

59
doc/doc.css Normal file
View File

@ -0,0 +1,59 @@
/* George Gesslein II's CSS for HTML documentation */
/* Commonly used classes: */
.clear { clear: both; }
.right { float: right; }
.left { float: left; }
.center { text-align: center; }
.middle { vertical-align: middle; }
.indent { margin-left: 2em; margin-right: 2em; }
.large { font-size: larger; }
.small { font-size: x-small; }
.sample {
border-style: solid; border-width: 1px; border-color: black;
border-radius: 7px;
color: black;
background-color: #FFFAF0;
padding: 10px;
}
a img { border: none; } /* don't draw borders around images that are links */
body {
font-family: sans-serif;
/* font-size: large; */
color: black;
background-color: white;
}
tt {
color: brown;
}
a:link {
color: blue;
}
a:visited {
color: purple;
}
a:hover {
color: green;
}
a:active {
color: red;
}
caption {
color: orange;
font-weight: bold;
}
@media print
{
a { text-decoration: none; } /* no underlined links when printing */
/* h2 { page-break-before: always; } Uncomment this to page break at the beginning of every section. */
}

BIN
doc/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

488
doc/fdl-1.3-standalone.html Normal file
View File

@ -0,0 +1,488 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>GNU Free Documentation License v1.3 - GNU Project - Free Software Foundation (FSF)</title>
<link rel="alternate" type="application/rdf+xml"
href="http://www.gnu.org/licenses/fdl-1.3.rdf" />
</head>
<body>
<h1 style="text-align: center;">GNU Free Documentation License</h1>
<p style="text-align: center;">Version 1.3, 3 November 2008</p>
<p> Copyright &copy; 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
&lt;<a href="http://fsf.org/">http://fsf.org/</a>&gt;
</p><p>Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.</p>
<h4><a name="section0"></a>0. PREAMBLE</h4>
<p>The purpose of this License is to make a manual, textbook, or other
functional and useful document &quot;free&quot; in the sense of freedom: to
assure everyone the effective freedom to copy and redistribute it,
with or without modifying it, either commercially or noncommercially.
Secondarily, this License preserves for the author and publisher a way
to get credit for their work, while not being considered responsible
for modifications made by others.</p>
<p>This License is a kind of &quot;copyleft&quot;, which means that derivative
works of the document must themselves be free in the same sense. It
complements the GNU General Public License, which is a copyleft
license designed for free software.</p>
<p>We have designed this License in order to use it for manuals for free
software, because free software needs free documentation: a free
program should come with manuals providing the same freedoms that the
software does. But this License is not limited to software manuals;
it can be used for any textual work, regardless of subject matter or
whether it is published as a printed book. We recommend this License
principally for works whose purpose is instruction or reference.</p>
<h4><a name="section1"></a>1. APPLICABILITY AND DEFINITIONS</h4>
<p>This License applies to any manual or other work, in any medium, that
contains a notice placed by the copyright holder saying it can be
distributed under the terms of this License. Such a notice grants a
world-wide, royalty-free license, unlimited in duration, to use that
work under the conditions stated herein. The &quot;Document&quot;, below,
refers to any such manual or work. Any member of the public is a
licensee, and is addressed as &quot;you&quot;. You accept the license if you
copy, modify or distribute the work in a way requiring permission
under copyright law.</p>
<p>A &quot;Modified Version&quot; of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.</p>
<p>A &quot;Secondary Section&quot; is a named appendix or a front-matter section of
the Document that deals exclusively with the relationship of the
publishers or authors of the Document to the Document's overall
subject (or to related matters) and contains nothing that could fall
directly within that overall subject. (Thus, if the Document is in
part a textbook of mathematics, a Secondary Section may not explain
any mathematics.) The relationship could be a matter of historical
connection with the subject or with related matters, or of legal,
commercial, philosophical, ethical or political position regarding
them.</p>
<p>The &quot;Invariant Sections&quot; are certain Secondary Sections whose titles
are designated, as being those of Invariant Sections, in the notice
that says that the Document is released under this License. If a
section does not fit the above definition of Secondary then it is not
allowed to be designated as Invariant. The Document may contain zero
Invariant Sections. If the Document does not identify any Invariant
Sections then there are none.</p>
<p>The &quot;Cover Texts&quot; are certain short passages of text that are listed,
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
the Document is released under this License. A Front-Cover Text may
be at most 5 words, and a Back-Cover Text may be at most 25 words.</p>
<p>A &quot;Transparent&quot; copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, that is suitable for revising the document
straightforwardly with generic text editors or (for images composed of
pixels) generic paint programs or (for drawings) some widely available
drawing editor, and that is suitable for input to text formatters or
for automatic translation to a variety of formats suitable for input
to text formatters. A copy made in an otherwise Transparent file
format whose markup, or absence of markup, has been arranged to thwart
or discourage subsequent modification by readers is not Transparent.
An image format is not Transparent if used for any substantial amount
of text. A copy that is not &quot;Transparent&quot; is called &quot;Opaque&quot;.</p>
<p>Examples of suitable formats for Transparent copies include plain
ASCII without markup, Texinfo input format, LaTeX input format, SGML
or XML using a publicly available DTD, and standard-conforming simple
HTML, PostScript or PDF designed for human modification. Examples of
transparent image formats include PNG, XCF and JPG. Opaque formats
include proprietary formats that can be read and edited only by
proprietary word processors, SGML or XML for which the DTD and/or
processing tools are not generally available, and the
machine-generated HTML, PostScript or PDF produced by some word
processors for output purposes only.</p>
<p>The &quot;Title Page&quot; means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the material
this License requires to appear in the title page. For works in
formats which do not have any title page as such, &quot;Title Page&quot; means
the text near the most prominent appearance of the work's title,
preceding the beginning of the body of the text.</p>
<p>The &quot;publisher&quot; means any person or entity that distributes copies of
the Document to the public.</p>
<p>A section &quot;Entitled XYZ&quot; means a named subunit of the Document whose
title either is precisely XYZ or contains XYZ in parentheses following
text that translates XYZ in another language. (Here XYZ stands for a
specific section name mentioned below, such as &quot;Acknowledgements&quot;,
&quot;Dedications&quot;, &quot;Endorsements&quot;, or &quot;History&quot;.) To &quot;Preserve the Title&quot;
of such a section when you modify the Document means that it remains a
section &quot;Entitled XYZ&quot; according to this definition.</p>
<p>The Document may include Warranty Disclaimers next to the notice which
states that this License applies to the Document. These Warranty
Disclaimers are considered to be included by reference in this
License, but only as regards disclaiming warranties: any other
implication that these Warranty Disclaimers may have is void and has
no effect on the meaning of this License.</p>
<h4><a name="section2"></a>2. VERBATIM COPYING</h4>
<p>You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the
copyright notices, and the license notice saying this License applies
to the Document are reproduced in all copies, and that you add no
other conditions whatsoever to those of this License. You may not use
technical measures to obstruct or control the reading or further
copying of the copies you make or distribute. However, you may accept
compensation in exchange for copies. If you distribute a large enough
number of copies you must also follow the conditions in section 3.</p>
<p>You may also lend copies, under the same conditions stated above, and
you may publicly display copies.</p>
<h4><a name="section3"></a>3. COPYING IN QUANTITY</h4>
<p>If you publish printed copies (or copies in media that commonly have
printed covers) of the Document, numbering more than 100, and the
Document's license notice requires Cover Texts, you must enclose the
copies in covers that carry, clearly and legibly, all these Cover
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
the back cover. Both covers must also clearly and legibly identify
you as the publisher of these copies. The front cover must present
the full title with all words of the title equally prominent and
visible. You may add other material on the covers in addition.
Copying with changes limited to the covers, as long as they preserve
the title of the Document and satisfy these conditions, can be treated
as verbatim copying in other respects.</p>
<p>If the required texts for either cover are too voluminous to fit
legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto adjacent
pages.</p>
<p>If you publish or distribute Opaque copies of the Document numbering
more than 100, you must either include a machine-readable Transparent
copy along with each Opaque copy, or state in or with each Opaque copy
a computer-network location from which the general network-using
public has access to download using public-standard network protocols
a complete Transparent copy of the Document, free of added material.
If you use the latter option, you must take reasonably prudent steps,
when you begin distribution of Opaque copies in quantity, to ensure
that this Transparent copy will remain thus accessible at the stated
location until at least one year after the last time you distribute an
Opaque copy (directly or through your agents or retailers) of that
edition to the public.</p>
<p>It is requested, but not required, that you contact the authors of the
Document well before redistributing any large number of copies, to
give them a chance to provide you with an updated version of the
Document.</p>
<h4><a name="section4"></a>4. MODIFICATIONS</h4>
<p>You may copy and distribute a Modified Version of the Document under
the conditions of sections 2 and 3 above, provided that you release
the Modified Version under precisely this License, with the Modified
Version filling the role of the Document, thus licensing distribution
and modification of the Modified Version to whoever possesses a copy
of it. In addition, you must do these things in the Modified Version:</p>
<ul>
<li>A. Use in the Title Page (and on the covers, if any) a title distinct
from that of the Document, and from those of previous versions
(which should, if there were any, be listed in the History section
of the Document). You may use the same title as a previous version
if the original publisher of that version gives permission.
</li>
<li>B. List on the Title Page, as authors, one or more persons or entities
responsible for authorship of the modifications in the Modified
Version, together with at least five of the principal authors of the
Document (all of its principal authors, if it has fewer than five),
unless they release you from this requirement.
</li>
<li>C. State on the Title page the name of the publisher of the
Modified Version, as the publisher.
</li>
<li>D. Preserve all the copyright notices of the Document.
</li>
<li>E. Add an appropriate copyright notice for your modifications
adjacent to the other copyright notices.
</li>
<li>F. Include, immediately after the copyright notices, a license notice
giving the public permission to use the Modified Version under the
terms of this License, in the form shown in the Addendum below.
</li>
<li>G. Preserve in that license notice the full lists of Invariant Sections
and required Cover Texts given in the Document's license notice.
</li>
<li>H. Include an unaltered copy of this License.
</li>
<li>I. Preserve the section Entitled &quot;History&quot;, Preserve its Title, and add
to it an item stating at least the title, year, new authors, and
publisher of the Modified Version as given on the Title Page. If
there is no section Entitled &quot;History&quot; in the Document, create one
stating the title, year, authors, and publisher of the Document as
given on its Title Page, then add an item describing the Modified
Version as stated in the previous sentence.
</li>
<li>J. Preserve the network location, if any, given in the Document for
public access to a Transparent copy of the Document, and likewise
the network locations given in the Document for previous versions
it was based on. These may be placed in the &quot;History&quot; section.
You may omit a network location for a work that was published at
least four years before the Document itself, or if the original
publisher of the version it refers to gives permission.
</li>
<li>K. For any section Entitled &quot;Acknowledgements&quot; or &quot;Dedications&quot;,
Preserve the Title of the section, and preserve in the section all
the substance and tone of each of the contributor acknowledgements
and/or dedications given therein.
</li>
<li>L. Preserve all the Invariant Sections of the Document,
unaltered in their text and in their titles. Section numbers
or the equivalent are not considered part of the section titles.
</li>
<li>M. Delete any section Entitled &quot;Endorsements&quot;. Such a section
may not be included in the Modified Version.
</li>
<li>N. Do not retitle any existing section to be Entitled &quot;Endorsements&quot;
or to conflict in title with any Invariant Section.
</li>
<li>O. Preserve any Warranty Disclaimers.</li>
</ul>
<p>If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no material
copied from the Document, you may at your option designate some or all
of these sections as invariant. To do this, add their titles to the
list of Invariant Sections in the Modified Version's license notice.
These titles must be distinct from any other section titles.</p>
<p>You may add a section Entitled &quot;Endorsements&quot;, provided it contains
nothing but endorsements of your Modified Version by various
parties&mdash;for example, statements of peer review or that the text has
been approved by an organization as the authoritative definition of a
standard.</p>
<p>You may add a passage of up to five words as a Front-Cover Text, and a
passage of up to 25 words as a Back-Cover Text, to the end of the list
of Cover Texts in the Modified Version. Only one passage of
Front-Cover Text and one of Back-Cover Text may be added by (or
through arrangements made by) any one entity. If the Document already
includes a cover text for the same cover, previously added by you or
by arrangement made by the same entity you are acting on behalf of,
you may not add another; but you may replace the old one, on explicit
permission from the previous publisher that added the old one.</p>
<p>The author(s) and publisher(s) of the Document do not by this License
give permission to use their names for publicity for or to assert or
imply endorsement of any Modified Version.</p>
<h4><a name="section5"></a>5. COMBINING DOCUMENTS</h4>
<p>You may combine the Document with other documents released under this
License, under the terms defined in section 4 above for modified
versions, provided that you include in the combination all of the
Invariant Sections of all of the original documents, unmodified, and
list them all as Invariant Sections of your combined work in its
license notice, and that you preserve all their Warranty Disclaimers.</p>
<p>The combined work need only contain one copy of this License, and
multiple identical Invariant Sections may be replaced with a single
copy. If there are multiple Invariant Sections with the same name but
different contents, make the title of each such section unique by
adding at the end of it, in parentheses, the name of the original
author or publisher of that section if known, or else a unique number.
Make the same adjustment to the section titles in the list of
Invariant Sections in the license notice of the combined work.</p>
<p>In the combination, you must combine any sections Entitled &quot;History&quot;
in the various original documents, forming one section Entitled
&quot;History&quot;; likewise combine any sections Entitled &quot;Acknowledgements&quot;,
and any sections Entitled &quot;Dedications&quot;. You must delete all sections
Entitled &quot;Endorsements&quot;.</p>
<h4><a name="section6"></a>6. COLLECTIONS OF DOCUMENTS</h4>
<p>You may make a collection consisting of the Document and other
documents released under this License, and replace the individual
copies of this License in the various documents with a single copy
that is included in the collection, provided that you follow the rules
of this License for verbatim copying of each of the documents in all
other respects.</p>
<p>You may extract a single document from such a collection, and
distribute it individually under this License, provided you insert a
copy of this License into the extracted document, and follow this
License in all other respects regarding verbatim copying of that
document.</p>
<h4><a name="section7"></a>7. AGGREGATION WITH INDEPENDENT WORKS</h4>
<p>A compilation of the Document or its derivatives with other separate
and independent documents or works, in or on a volume of a storage or
distribution medium, is called an &quot;aggregate&quot; if the copyright
resulting from the compilation is not used to limit the legal rights
of the compilation's users beyond what the individual works permit.
When the Document is included in an aggregate, this License does not
apply to the other works in the aggregate which are not themselves
derivative works of the Document.</p>
<p>If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one half of
the entire aggregate, the Document's Cover Texts may be placed on
covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic form.
Otherwise they must appear on printed covers that bracket the whole
aggregate.</p>
<h4><a name="section8"></a>8. TRANSLATION</h4>
<p>Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section 4.
Replacing Invariant Sections with translations requires special
permission from their copyright holders, but you may include
translations of some or all Invariant Sections in addition to the
original versions of these Invariant Sections. You may include a
translation of this License, and all the license notices in the
Document, and any Warranty Disclaimers, provided that you also include
the original English version of this License and the original versions
of those notices and disclaimers. In case of a disagreement between
the translation and the original version of this License or a notice
or disclaimer, the original version will prevail.</p>
<p>If a section in the Document is Entitled &quot;Acknowledgements&quot;,
&quot;Dedications&quot;, or &quot;History&quot;, the requirement (section 4) to Preserve
its Title (section 1) will typically require changing the actual
title.</p>
<h4><a name="section9"></a>9. TERMINATION</h4>
<p>You may not copy, modify, sublicense, or distribute the Document
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense, or distribute it is void, and
will automatically terminate your rights under this License.</p>
<p>However, if you cease all violation of this License, then your license
from a particular copyright holder is reinstated (a) provisionally,
unless and until the copyright holder explicitly and finally
terminates your license, and (b) permanently, if the copyright holder
fails to notify you of the violation by some reasonable means prior to
60 days after the cessation.</p>
<p>Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.</p>
<p>Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, receipt of a copy of some or all of the same material does
not give you any rights to use it.</p>
<h4><a name="section10"></a>10. FUTURE REVISIONS OF THIS LICENSE</h4>
<p>The Free Software Foundation may publish new, revised versions of the
GNU Free Documentation License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in
detail to address new problems or concerns. See
<a href="http://www.gnu.org/copyleft/">http://www.gnu.org/copyleft/</a>.</p>
<p>Each version of the License is given a distinguishing version number.
If the Document specifies that a particular numbered version of this
License &quot;or any later version&quot; applies to it, you have the option of
following the terms and conditions either of that specified version or
of any later version that has been published (not as a draft) by the
Free Software Foundation. If the Document does not specify a version
number of this License, you may choose any version ever published (not
as a draft) by the Free Software Foundation. If the Document
specifies that a proxy can decide which future versions of this
License can be used, that proxy's public statement of acceptance of a
version permanently authorizes you to choose that version for the
Document.</p>
<h4><a name="section11"></a>11. RELICENSING</h4>
<p>&quot;Massive Multiauthor Collaboration Site&quot; (or &quot;MMC Site&quot;) means any
World Wide Web server that publishes copyrightable works and also
provides prominent facilities for anybody to edit those works. A
public wiki that anybody can edit is an example of such a server. A
&quot;Massive Multiauthor Collaboration&quot; (or &quot;MMC&quot;) contained in the site
means any set of copyrightable works thus published on the MMC site.</p>
<p>&quot;CC-BY-SA&quot; means the Creative Commons Attribution-Share Alike 3.0
license published by Creative Commons Corporation, a not-for-profit
corporation with a principal place of business in San Francisco,
California, as well as future copyleft versions of that license
published by that same organization.</p>
<p>&quot;Incorporate&quot; means to publish or republish a Document, in whole or in
part, as part of another Document.</p>
<p>An MMC is &quot;eligible for relicensing&quot; if it is licensed under this
License, and if all works that were first published under this License
somewhere other than this MMC, and subsequently incorporated in whole or
in part into the MMC, (1) had no cover texts or invariant sections, and
(2) were thus incorporated prior to November 1, 2008.</p>
<p>The operator of an MMC Site may republish an MMC contained in the site
under CC-BY-SA on the same site at any time before August 1, 2009,
provided the MMC is eligible for relicensing.</p>
<h3><a name="addendum"></a>ADDENDUM: How to use this License for your documents</h3>
<p>To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and
license notices just after the title page:</p>
<pre> Copyright (C) YEAR YOUR NAME.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled &quot;GNU
Free Documentation License&quot;.
</pre>
<p>If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
replace the &quot;with &hellip; Texts.&quot; line with this:</p>
<pre> with the Invariant Sections being LIST THEIR TITLES, with the
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
</pre>
<p>If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.</p>
<p>If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of
free software license, such as the GNU General Public License,
to permit their use in free software.
</p>
</body></html>

BIN
doc/gnu-fdl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
doc/greenfade.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 893 B

87
doc/index.html Normal file
View File

@ -0,0 +1,87 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Official Mathomatic user documentation, top level</title>
<meta name="description" content="The top level of the complete, official Mathomatic user documentation in HTML.">
<meta name="keywords" content="Mathomatic computer algebra system, user documentation, manual, reference, index">
<meta name="author" content="George Gesslein II">
<meta name="distribution" content="global">
<meta name="rating" content="general">
<meta name="copyright" content="&copy; 1987-2012 George Gesslein II">
<link rel="author" href="http://www.google.com/profiles/georgegesslein">
<link rel="license" href="http://www.gnu.org/licenses/fdl-1.3.html">
<link rel="home" href="http://www.mathomatic.org">
<link rel="next" href="manual.html">
<LINK media="print" title="The Mathomatic User Guide and Command Reference in PDF format"
type="application/pdf"
rel="alternate"
href="http://mathomatic.org/manual.pdf">
<link rel="shortcut icon" href="/favicon.ico">
<link rel="stylesheet" type="text/css" href="doc.css">
</head>
<body>
<h1><img src="open_book_nae_02.png" alt="outline of book"> Official Documentation for Mathomatic</h1>
<h2>HTML User Guides:</h2>
<blockquote class="large">
<a href="manual.html"><img src="led_circle_green.png" alt="button">
The Mathomatic User Guide</a>
<br>
<a href="am.html"><img src="led_circle_green.png" alt="button">
The Mathomatic Command Reference</a>
<br>
<a href="mathomatic.1.html"><img src="led_circle_green.png" alt="button">
The Unix/Linux man page for Mathomatic</a>
<br>
<a href="rmath.1.html"><img src="led_circle_green.png" alt="button">
The rmath application man page (m4 Mathomatic)</a>
<br>
<a href="matho-primes.1.html"><img src="led_circle_green.png" alt="button">
The matho-primes utility man page</a>
<br>
<a href="primorial.1.html"><img src="led_circle_green.png" alt="button">
The primorial utility man page</a>
</blockquote>
<p>
This HTML format documentation is easily viewed and printed using your web browser.
<h2>PDF User Guides:</h2>
<p>
For the PDFs, see the online
<a href="http://mathomatic.org/manual.pdf">Mathomatic User Guide and Command Reference PDF file</a> in a file called "<i>manual.pdf</i>",
or all <a href="http://mathomatic.org/bookman.pdf">Unix/Linux man pages for Mathomatic</a> in one PDF file called "<i>bookman.pdf</i>".
PDFs are generally used when you want to print out a hardcopy 8.5-inch by 11-inch manual, but they can be browsed
with a PDF document viewer and saved to disk easily, too.
<hr>
<p>
<a target="_blank" rel="nofollow" href="http://www.gnu.org/copyleft/fdl.html"><img src="gnu-fdl.png" alt="GFDL logo"></a>
<font color="red">Mathomatic documentation copyright &copy; 1987-2012 George Gesslein II</font>
<p>
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included <a href="fdl-1.3-standalone.html">here</a>
in the Mathomatic documentation directory.
<br>
<br>
<hr>
<form class="left" action="http://www.mathomatic.org/math/"><input type="button" value="Back to Previous Page" onClick="history.back()"></form>
<a class="right" href="http://www.mathomatic.org" title="Go to the Mathomatic home page"><img src="mathomatic16x16.png" alt="Mathomatic icon"> www.mathomatic.org</a>
</body>
</html>

BIN
doc/led_circle_green.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

795
doc/manual.html Normal file
View File

@ -0,0 +1,795 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Mathomatic User Guide</title>
<meta name="description" content="The User Guide for the Mathomatic computer algebra system.">
<meta name="author" content="George Gesslein II">
<meta name="distribution" content="global">
<meta name="rating" content="general">
<meta name="copyright" content="&copy; 1987-2012 George Gesslein II">
<link rel="author" href="http://www.google.com/profiles/georgegesslein">
<link rel="license" href="http://www.gnu.org/licenses/fdl-1.3.html">
<link rel="home" href="http://www.mathomatic.org">
<link rel="contents" href="index.html">
<link rel="index" href="index.html">
<link rel="next" href="am.html">
<link rel="previous" href="index.html">
<link rel="start" title="The first page of the Mathomatic User Guide" type="text/html" href="index.html">
<LINK media="print" title="The Mathomatic User Guide and Command Reference in PDF format"
type="application/pdf"
rel="alternate"
href="http://mathomatic.org/manual.pdf">
<link rel="shortcut icon" href="/favicon.ico">
<link rel="stylesheet" type="text/css" href="doc.css">
</head>
<body>
<center>
<h1>Mathomatic User Guide</h1>
<img src="greenfade.png" alt="decoration line">
</center>
<h3>Table of Contents</h3>
<ol>
<li>
<a href="#introduction">Introduction and Features</a>
<li>
<a href="#history">History</a>
<li>
<a href="#developer">Developer Information</a>
<li>
<a href="#startup">Startup</a>
<li>
<a href="#equations">Equations and Expressions</a>
<ol type="a">
<li>
<a href="#equationsonly">Equations</a>
<li>
<a href="#nonequations">Non-Equations</a>
<li>
<a href="#constants">Constants</a>
<li>
<a href="#symbols">Variables</a>
<li>
<a href="#operators">Operators</a>
<ol>
<li>
<a href="#order">Order of Operations example</a>
</ol>
<li>
<a href="#complex">Complex Numbers</a>
</ol>
<li>
<a href="#commands">Commands</a>
<li>
<a href="#license">Documentation License</a>
</ol>
<p>
<a href="am.html">Mathomatic Command Reference</a>
<br>
<br>
<hr>
<a name="introduction"></a>
<h2>Introduction and Features</h2>
<p>
Mathomatic is an easy to use and colorful algebra calculator that can symbolically:
<ul>
<li>
combine and solve equations containing many variables,
<li>
completely simplify and compare mathematical expressions and equations,
<li>
do simple calculus transformations and series, sum (&sum;) and product (&prod;),
<li>
perform generalized real number, complex number, modular, and polynomial arithmetic,
<li>
generate efficient C, Java, or Python language code from simplified equations,
<li>
plot expressions with <a target="_blank" rel="nofollow" href="http://gnuplot.sourceforge.net">gnuplot</a> in two or three dimensions, etc.
</ul>
<p>
The name "Mathomatic" is a portmanteau of "math" and "automatic".
It is a unique computer algebra system (CAS),
in that all <a href="#constants">constants</a> are one or more floating point values.
All numeric arithmetic is IEEE standard floating point arithmetic,
which most computers do very quickly.
Mathomatic is written entirely in C,
which is like a CAS written in assembly language,
running as fast as the computer allows
without any high-level language overhead.
<p>
Mathomatic is exceptionally good at solving, differentiating,
simplifying, calculating, and visualizing elementary algebra.
It is a console mode application using a color command-line interface (CLI)
with pretty-print output that runs in a terminal emulator under any operating system.
"The console interface is very simple and requires little more
than learning the basic algebra notation to get started,"
a Mathomatic user says joyfully on
<a target="_blank" title="Wikipedia article on Mathomatic" href="http://en.wikipedia.org/wiki/Mathomatic#Features">Wikipedia</a>.
All input and output is line at a time ASCII text.
By default, input is standard input and output is standard output.
Mathomatic can be compiled with editline or GNU readline for easier line input.
The pretty-print output is even prettier in HTML output mode, which supports color too.
<br>
<br>
<hr>
<a name="history"></a>
<h2>History</h2>
<p>
Mathomatic has been developed and supported almost every day by George Gesslein II,
with help from the Internet community.
<p>
Mathomatic development started in the year 1986 to test new ideas
and as an experiment in computerized mathematics,
originally using the Microsoft C compiler for DOS and the author's own text editor as the only development tools.
Versions 1 and 2 were published by Dynacomp
of Rochester, New York in 1987 and 1988 as a scientific software product for DOS.
Afterwards it was released as shareware and then emailware,
with a 2D equation graphing program that could find asymptotes,
written in Microsoft C for DOS.
At the turn of the century, Mathomatic was ported
to the GNU C Compiler (gcc) under Linux and became
free and open source software by publishing under the
GNU Lesser General Public License
(<a target="_blank" rel="nofollow" href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">LGPL version 2.1</a>).
The graphing program was discontinued;
2D/3D graphing of equations is now accomplished with gnuplot.
<p>
Mathomatic is currently developed and maintained on a Linux x86-64-bit computer
and now stands at 23,000 lines of code (including comments).
It has been optimized for speed, by using Linux debugging
utilities that tell where Mathomatic spends most of its time.
<br>
<br>
<hr>
<a name="developer"></a>
<h2>Developer Information</h2>
<p>
Building Mathomatic from source requires a C compiler with the standard C libraries.
If compiled with the <a target="_blank" rel="nofollow" href="http://gcc.gnu.org">GCC</a> C compiler
or the Tiny C Compiler for a Unix-like operating system,
no changes need to be made to the source code.
See the file <a rel="nofollow" href="http://mathomatic.org/README.txt"><i>README.txt</i></a>
for compilation instructions.
Mathomatic uses no special GCC only code, so it will usually compile easily with any C compiler.
<p>
Mathomatic can easily be ported to any computer with at least 1 megabyte of free RAM.
In the standard distribution,
found on the <a href="http://www.mathomatic.org">Mathomatic home page</a>,
the maximum memory usage defaults to 400 megabytes
(the "<a href="am.html#version">version</a> status" command tells this).
Maximum memory usage is not reached unless all equation spaces are filled.
The default maximum memory usage should be less than the amount of free RAM,
and can be easily reduced by compiling with the "<b>-DHANDHELD</b>" compiler command-line option,
which reduces the memory requirements to 1/6th of the default size.
Memory usage can also be dynamically changed at startup with the
<a href="mathomatic.1.html"><b>-m</b> option</a>.
<p>
The Mathomatic source code can also be compiled
as a symbolic math library that is callable
from any C compatible program and is mostly operating system independent.
See the file <i>lib/README.txt</i> for more developer information
and how to include Mathomatic in your free software or proprietary program.
<p>
Very little disk space (a few megabytes) is required to compile, install, and run
the Mathomatic application.
<p>
A <b>readline</b> library must be installed to compile-in and use readline capabilities,
which allows editing and history recall of all
Mathomatic line input by pressing the cursor keys.
We use <b>editline</b> instead of GNU readline,
which is in a free Linux package called: "libeditline-dev".
It is more compact and license compatible, than GNU readline.
<br>
<br>
<hr>
<a name="startup"></a>
<h2>Startup</h2>
<dl>
<dt>
SYNOPSIS
<dd>
<b>mathomatic</b> [ options ] [ input_files or input ]
<br>
<b>rmath</b> [ input_files ]
</dl>
<p>
To start the compiled, interactive Mathomatic application,
run a terminal emulator which opens a shell window,
and type "mathomatic" at the shell prompt (without double quotes).
If m4 (macro) Mathomatic was installed, you may type "rmath" instead, to
use Mathomatic with input of functions like <tt>sin(x)</tt> and <tt>sqrt(x)</tt>
allowed and automatically expanded to equivalent algebraic expressions.
Logarithm function input is currently not available,
because the logarithm function has not yet been implemented
in the Mathomatic symbolic math engine.
<p>
If you are wondering what to try first in Mathomatic,
type "help examples" at the Mathomatic prompt.
<p>
Color mode is toggled by the <b>-c</b> option on the shell command-line,
like this:
<pre class="indent">
$ mathomatic -c
</pre>
ANSI color mode is the default, which outputs ANSI terminal escape sequences
to make each level of parentheses a different color, improving readability.
If ANSI color mode is on, an ANSI compatible terminal emulator is required.
If the colors are hard to see,
use the <b>-b</b> option instead, which will always turn on
bold color mode, increasing the color brightness.
<p>
The other options are described in the
<a href="mathomatic.1.html">Unix/Linux man page for Mathomatic</a>.
After any options, text files may be specified on the shell command-line
that will be automatically read in with the <a href="am.html#read">read command</a>,
unless the <b>-e</b> option is specified, in which case
mathematical expressions and Mathomatic commands are expected,
separated by unquoted space characters.
<p>
It is recommended that the name <i>mathomatic</i> be shortened to <i>am</i>
and <i>e</i> for quicker and easier access from the shell command-line.
This can be done in the Bash shell by adding the following two lines to your <i>~/.bashrc</i> file:
<pre class="indent">
alias am=mathomatic
alias e="mathomatic -e --"
</pre>
<p>
Then just typing "am" at the shell prompt will run Mathomatic as an interactive application.
Typing "e" followed by a quoted mathematical expression at the shell prompt will
quickly and silently bring up Mathomatic and calculate and display the result.
"am" stands for "algebraic manipulator", and "e" stands for "evaluate".
<br>
<br>
<hr>
<a name="equations"></a>
<h2>Equations and Expressions</h2>
<p>
On the World Wide Web are some simple algebra texts:
<a target="_blank" rel="nofollow" href="http://www.mathsisfun.com/algebra/definitions.html">like those at MathsIsFun.com
for some basic algebra definitions, suitable for children</a>, and of course
<a href="https://secure.wikimedia.org/wikipedia/simple/wiki/Algebra">The Simple English Wikipedia</a>,
which is usually easier to understand than The English Wikipedia.
The English Wikipedia contains much more advanced mathematics.
<p>
Mathematical equations and expressions are entered
into Mathomatic <strong>equation spaces</strong> by typing, pasting,
or <a href="am.html#read">reading</a> them in at the main prompt.
The maximum number and size of available equation spaces is displayed
every time Mathomatic starts up.
When an expression grows larger than half the equation space size,
processing stops and the "Expression too large" message is displayed,
returning you to the main prompt.
The reason it does this is because each equation space consists of two equation sides,
which are fixed size arrays that are easily manipulated by the software.
<p>
Each equation space is successively numbered with an <strong>equation number</strong> (starting at 1).
The main prompt "1&mdash;&gt;&nbsp;" contains the equation number of the current equation space.
The current equation can be changed by typing a valid equation number at the main prompt
(called <a href="am.html#selecting">selecting an equation space</a>),
or by entering another equation or expression, which becomes the current equation.
<p>
Any previously entered expression can be automatically entered again by entering a "#"
followed by the relative or absolute equation space number of that expression.
If this is entered first thing at the main prompt,
it means something entirely different, that you are <a href="am.html#selecting">selecting that equation space</a>;
Otherwise, the RHS or expression at that equation space is substituted, for your convenience.
<a name="equationsonly"></a>
<h3>Equations</h3>
<p>
To enter an equation into the first available equation space
and make it the current equation, simply type or copy/paste it in at the main prompt.
Each equation space consists of two equation sides,
called the Left-Hand Side (LHS) and the Right-Hand Side (RHS),
separated by an equals sign (<b>=</b>).
Each equation side consists of a mathematical expression,
which is a mix of <a href="#constants">constants</a>,
<a href="#symbols">variables</a>, and <a href="#operators">operators</a>,
mostly in standard algebraic infix notation.
Parentheses are used to override operator precedence and group things together.
Valid parentheses characters are <b>()</b> and <b>{}</b>.
<b>[]</b> are reserved for array subscripts in variable names.
<p>
Note that the equals sign does not make an assignment to any variables,
it only signifies equality (sameness) between the results of evaluating the LHS and RHS.
Shown here is a valid equation with its parts labeled:
<pre class="indent">
equation
-----------------------
| variables constant|
|-------------- | |
|| | | | |
<b> a = b - (c + 2)</b>
| | | | | |
| | | -------- |
| | | operators |
--- -----------------
LHS RHS
</pre>
<p>
In the above equation, the variable <b>a</b> is called the <strong>dependent</strong>
variable because its value depends on the <strong>independent</strong> variables <b>b</b> and <b>c</b>.
In Mathomatic,
any variable can be made the dependent variable by simply typing
the variable name in at the prompt.
This will <a href="am.html#solving">solve</a> the current equation
for that variable and, if successful, make that variable the LHS.
<p>
Here is the above equation entered into Mathomatic and solved for <b>b</b>,
then <a href="am.html#calculate">calculated</a> for the values <b>a=1</b> and <b>c=1</b>:
<pre class="sample">
1&mdash;&gt; a=b-(c+2)
#1: a = b &minus; c &minus; 2
1&mdash;&gt; b
#1: b = 2 + c + a
1&mdash;&gt; calculate
Enter a: 1
Enter c: 1
b = 4
1&mdash;&gt;
</pre>
<p>
The "#1:" listed in front of each displayed equation
always indicates the equation space number it is stored in.
<p>
Mathomatic automatically does both symbolic and numeric
mathematics computations during any manipulations.
This means that it can handle algebraic formulas, as well as numbers.
What follows is a simple example of the result of both types of computations
working together during equation simplification and solving:
<pre class="sample">
1&mdash;&gt; 3*(x-1) + 1 = 2x + 1
#1: (3&middot;(x &minus; 1)) + 1 = (2&middot;x) + 1
1&mdash;&gt; simplify
#1: (3&middot;x) &minus; 2 = (2&middot;x) + 1
1&mdash;&gt; solve verify x
#1: x = 3
Solution verified.
1&mdash;&gt;
</pre>
<p>
The "solve verify" command, used above, solves the current equation
and then verifies the result by plugging the result into the original equation
and simplifying.
If an identity results (the LHS is identical to the RHS),
a "Solution verified" message is displayed,
otherwise "Solution might be incorrect" is displayed.
<a name="nonequations"></a>
<h3>Expressions that are not equations</h3>
<p>
Non-equations, that is any mathematical expression without an equals sign,
may be entered into equation spaces too.
However, if the expression entered at the main prompt contains no variables,
it will be calculated and displayed with the <a href="am.html#calculate">calculate command</a>,
unless the <a href="am.html#set">autocalc or auto</a> option is turned off.
<p>
Non-equations cannot be solved,
unless you set them equal to zero or something,
then they become an equation.
Non-equations are stored in the first equation side (LHS) for that equation space.
The RHS will be empty (size 0).
<a name="constants"></a>
<h3>Constants</h3>
<p>
In Mathomatic, numeric arithmetic is double precision floating point
with about 14 decimal digits accuracy.
Many results will be exact, because symbolic math is an exact math,
and because multiple floating point numbers
can be combined for a single mathematical value; for example: <b>2^(1/3)</b>,
which is the cube root of 2 exactly.
<p>
Constants are approximated real numbers stored internally as
IEEE 754 standard 64-bit (8 bytes) double precision floating point values.
They may be entered as decimal (base 10) numbers in normal notation or in scientific notation
(also called exponential notation).
Constants may also be entered in hexadecimal (base 16)
by starting them with "0x".
<p>
Constants are displayed in decimal (base 10, rounded to 14 digits)
using either normal or scientific notation,
whichever is shortest.
Results are usually accurate from 12 to 14 digits,
due to accumulated round-off error,
because all constants are stored internally
as double precision (rounded to 15 decimal digits) floats.
And the amount of round-off error is not tracked, making Mathomatic
unsuitable for applications requiring high precision,
like astronomical calculations.
<p>
Excepting constants with a name (like "inf" for the infinity constant),
constants always start with a decimal digit (0..9), a period, or a dash (-).
<p>
Examples of equivalent constants follow:
</p>
<table summary="constant notation examples" border=1 cellpadding=5>
<tr>
<th>
Normal Notation (base 10)
</th>
<th>
Scientific Notation (base 10)
</th>
<th>
Hexadecimal Notation (base 16)
</th>
</tr>
<tr>
<td>
10
</td>
<td>
1e1 (1.0 times 10<sup>1</sup>)
</td>
<td>
0xa
</td>
</tr>
<tr>
<td>
.125
</td>
<td>
1.25e-1 (1.25 times 10<sup>-1</sup>)
</td>
<td>
0x.2
</td>
</tr>
<tr>
<td>
255
</td>
<td>
2.55e2 (2.55 times 10<sup>2</sup>)
</td>
<td>
0xff
</td>
</tr>
</table>
<p>
The exact syntax to enter constants as above may be found by
looking up the C library function <code>strtod(3)</code>.
In the Unix shell, <tt>"man strtod"</tt> will do that.
<p>
Double precision floating point limits:
<ul>
<li>
The largest valid constant is <b>&plusmn;1.797693e+308</b> (slightly less than 2^1024).
<li>
The smallest valid constant is <b>&plusmn;2.225074e-308</b> or 0.
</ul>
<p>
The infinity constant is entered by typing "inf".
Positive and negative infinity are distinct and understood,
however division by zero produces one infinity value,
not the two-valued &plusmn;infinity which would be more correct.
Also, floating point overflow produces either positive or negative infinity.
<pre class="sample">
1&mdash;&gt; 1/0
Warning: Division by zero.
answer = inf
1&mdash;&gt; 0/0
Warning: Division by zero.
answer = nan
1&mdash;&gt;
</pre>
<p>
<i>nan</i> or <i>NaN</i> stands for <b>Not a Number</b> and it
means an invalid or indeterminate floating point arithmetic result.
<i>NaN</i> cannot be directly entered into Mathomatic.
The appearance of the constant <i>NaN</i> in an expression
means the expression is unusable.
<p>
Fractions (such as <b>100/101</b>) are preserved if
the numerator and denominator are not large.
Fractions are always presented in fully reduced form;
for example, <b>6/9</b> is converted to the irreducible fraction <b>2/3</b>.
Constants which are exactly equal to a fraction are converted and displayed
as fully reduced fractions; for example, <b>0.5</b> converts to <b>1/2</b>.
Mathomatic internally converts a fraction to a single floating point value,
then may convert it back to a fraction for display
after all floating point arithmetic has been done,
if the result is equal to a fraction.
<p>
Irrational numbers, such as the square root of two (<b>2^(1/2)</b>) and <b>pi</b>,
are preserved and simplified for exactness,
unless explicitly approximated.
<p>
Denominators of fractions are usually rationalized in Mathomatic; for example, <b>1/(2^(1/2))</b> becomes
the equivalent <b>(2^(1/2))/2</b> upon simplification.
This can be turned off with the command "<a href="am.html#set">set</a> no rationalize_denominators".
<a name="symbols"></a>
<h3>Variables</h3>
<p>
Variables are what Mathomatic is all about.
That is where the term "symbolic" comes from,
because variables are symbolic in nature.
They are symbols that can represent known or unknown values,
or any expression.
Variables need not be defined in Mathomatic,
just entering the variable name is enough.
<p>
Variable names consist of any combination of letters (a..z),
digits (0..9), and underscores (_).
They never start with a digit.
By using the "<a href="am.html#set">set</a> special_variable_characters" command,
you can add to the allowed variable name characters.
By default, letters in variable names are case sensitive,
meaning the alphabetic case of each letter in the variable name is important.
For example, variables named "A1" and "a1" represent two different variables,
unless "<a href="am.html#set">set</a> no case_sensitive" is entered beforehand.
<p>
The following variables are predefined and are not normal variables:
<div class="indent">
<b>e</b>, <b>&ecirc;</b>, or <b>e#</b> - the universal constant e (2.718281828&hellip;)<br>
<b>pi</b> or <b>pi#</b> - the universal constant pi (3.1415926&hellip;)<br>
<b>i</b>, <b>&icirc;</b>, or <b>i#</b> - the imaginary unit (square root of -1)<br>
<b>sign</b>, <b>sign1</b>, <b>sign2</b>, &hellip; - may only be +1 or -1<br>
<b>integer</b>, <b>integer1</b>, &hellip; - may be any integer value
</div>
<p>
The above can be used anywhere variables are required.
<p>
To automatically enter multiplication by a unique, two-valued "sign" variable,
precede any expression with "+/&minus;".
<a name="operators"></a>
<h3>Operators</h3>
<p>
Mathomatic implements the standard rules of algebra for
addition (<b>+</b>), subtraction (<b>&minus;</b>), multiplication (<b>*</b>),
division (<b>/</b>), modulus (<b>%</b>), and all forms of exponentiation (<b>^</b> or <b>**</b>).
An example of a rule of algebra is <b>2*x + 3*x</b> being simplified to <b>5*x</b>.
<p>
All available operators are at least numerically capable
(most are symbolically capable too, see above paragraph) and
have precedence decreasing as indicated:
<pre class="indent">
<b>!</b> factorial (same as gamma(x+1) function; highest precedence)
<b>**</b> or <b>^</b> power (exponentiation; high precedence)
<b>*</b> multiply <b>/</b> divide <b>%</b> modulus <b>//</b> integral divide
<b>+</b> add <b>&minus;</b> subtract or negate
<b>=</b> equate (denotes equivalence; lowest precedence)
</pre>
<p>
Higher precedence operators are grouped (or evaluated) first,
then multiple operators of the same precedence level are grouped left to right.
This is called the "<a href="#order">order of operations</a>".
To group power operators from right to left, like most math programs do,
enter "<a href="am.html#set">set</a> right_associative_power" at the main prompt.
<p>
The default operator is multiply (<b>*</b>).
If an expression (operand) is entered when an operator is expected,
a multiply operator is automatically inserted.
For example, entering <b>2x</b>, <b>2(x)</b>, <b>(2)x</b>, and <b>(2)(x)</b>
all result in the expression <b>2*x</b>.
<p>
<a name="modular"></a>
The modulus operator <b>(a % b)</b> (spoken as "a modulo b")
gives the remainder of the division <b>(a / b)</b>,
which allows modular arithmetic;
also known as clock arithmetic, because the numbers wrap around, after they reach the modulus.
Mathomatic can simplify, calculate, and sometimes even solve modular arithmetic.
Using "integer" variables allows further modulus simplification
when using the <a href="am.html#simplify">simplify command</a>.
An integer variable is specified by using a variable name that starts with "integer",
like "integer1", "integer_x", etc.
The resulting sign of any numerical modulus operation depends
upon the "<a href="am.html#set">set</a> modulus_mode" option.
<p>
The integral divide operator <b>(a // b)</b> divides <b>a</b> by <b>b</b>
and then truncates by zeroing the fractional part to make the result an integer.
For example, <b>(8 // 3)</b> results in 2, which is useful when doing integer arithmetic.
This operator currently implements no rules of algebra,
and will not evaluate if an operand is a complex number.
<p>
Factorials <b>x!</b> use the gamma function <b>gamma(x+1)</b>,
so that the factorial operator works with any real number,
not just the positive integers.
The factorial operator currently implements no rules of algebra,
and will not evaluate for complex numbers or if an overflow happens.
<p>
Absolute value notation is allowed,
<b>|x|</b> is always converted to <b>(x^2)^.5</b>.
This is not the same as standard absolute value
where the real and imaginary parts of complex numbers are separated out and then
plugged into the distance formula (the Pythagorean theorem),
returning a real distance value,
but it works the same when given real number values with no imaginary units.
The absolute value operation <b>|x|</b> results in a positive value for any <b>x</b> value;
that is, if -1 is a factor, it is removed.
With Mathomatic, if <b>x</b> is imaginary, you may get an unwanted imaginary result,
but it will be positive!
<a name="order"></a>
<h4>Order of Operations example</h4>
<p>
The following example shows why operator precedence is important.
Given the numerical expression:
<pre class="indent">
64/(-2)^4 + 6*(3+1)
</pre>
<p>
Mathomatic will parenthesize the highest precedence operators first:
power, then times and divide.
Addition and subtraction are the lowest precedence, so no need
to parenthesize them.
The result will be:
<pre class="indent">
(64/((-2)^4)) + (6*(3+1))
</pre>
<p>
This is evaluated by combining constants from left to right
on the same level of parentheses, deepest levels first.
So the calculations are performed in the following order:
<pre class="indent">
(64/16) + (6*4) Combine deepest level parentheses first.
4 + 24 Divided 64 by 16 and multiplied 6 by 4.
28 Added 24 to 4.
</pre>
<p>
If the calculations were performed in a different order,
the result would be different.
<a name="complex"></a>
<h3>Complex Numbers</h3>
<p>
Mathomatic automatically performs complex number addition, subtraction,
multiplication, division, and exponentiation.
It can also approximate roots of real and complex numbers,
giving a single result;
when multiple results are possible,
the first real number result is chosen.
To view all roots of a complex number,
use the <a href="am.html#roots">roots command</a>.
<p>
Complex numbers are usually of the form:
<pre class="indent">
a + b*i
</pre>
<p>
where <b>a</b> is the <a href="am.html#real">real part</a> (a real number)
and <b>b</b> is the <a href="am.html#imaginary">imaginary part</a> (an imaginary number).
<b>i</b> is the "imaginary unit" and it represents the square root of -1
("<b>(-1)^.5</b>" in Mathomatic notation; additionally "<b>sqrt(-1)</b>" in m4 Mathomatic notation).
<pre class="indent">
a + b*i
</pre>
<p>
is the rectangular coordinate form of a complex number.
To view the polar coordinate form, use the <a href="am.html#roots">roots command</a>.
<p>
The imaginary unit <b>i</b> may appear anywhere within an expression,
as many times as you want, Mathomatic will handle and simplify it properly.
<p>
As an example of imaginary numbers being produced, <b>(-2)^.5</b> will be converted
to <b>(2^.5)*i</b>.
<p>
Roots of complex numbers, such as <b>i^.5</b> and <b>.5^i</b>, will be approximated, and
only a single root will be produced,
even though there may be many roots (see the <a href="am.html#roots">roots command</a>).
That single root is called the "principal value",
which may be unexpected and will often be inexact.
<p>
Because <b>1/i</b> correctly simplifies to <b>-i</b>, after significant manipulation
different numerical results might be produced with complex numbers and division.
This is normal, so the sooner the result of a complex expression is calculated, the better.
<p>
Conjugation of all complex numbers in the current equation
is accomplished by typing the following command:
<pre class="indent">
replace i with -i
</pre>
<br>
<br>
<hr>
<a name="commands"></a>
<h2>Commands</h2>
<p>
Mathomatic has about <a href="quickrefcard.html">43 simple English commands</a> that may be typed at the main prompt.
Please consult the <a href="am.html">Mathomatic Command Reference</a>,
for detailed information on all commands.
<br>
<br>
<hr>
<a name="license"></a>
<h2>Documentation License</h2>
<p>
<a target="_blank" rel="nofollow" href="http://www.gnu.org/copyleft/fdl.html"><img src="gnu-fdl.png" alt="GFDL logo"></a>
<font color="red">Mathomatic documentation copyright &copy; 1987-2012 George Gesslein II</font>
<p>
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included <a href="fdl-1.3-standalone.html">here</a>
in the Mathomatic documentation directory.
<br>
<br>
<hr>
<a class="left" href="index.html">Up to the documentation index</a>
<a class="right" href="http://www.mathomatic.org" title="Go to the Mathomatic home page"><img src="mathomatic16x16.png" alt="Mathomatic icon"> www.mathomatic.org</a>
</body>
</html>

64
doc/matho-mult.1.html Normal file
View File

@ -0,0 +1,64 @@
<!-- manual page source format generated by PolyglotMan v3.2, -->
<!-- available at http://polyglotman.sourceforge.net/ -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux (vers 25 March 2009), see www.w3.org">
<title>MATHO-MULT(1) manual page</title>
</head>
<body bgcolor='white'>
<a href='#toc'>Table of Contents</a>
<h2><a name='sect0' href='#toc0'>Name</a></h2>matho-mult -
multiply large integers
<h2><a name='sect1' href=
'#toc1'>Synopsis</a></h2><b>matho-mult</b> [integers]
<h2><a name='sect2' href='#toc2'>Description</a></h2>This
command-line utility is optionally part of the <a href=
'mathomatic.1.html'><b>mathomatic</b>(1)</a> package. It uses
Python to multiply many large integers separated by spaces or
newlines. The size of the integers is only limited by the
available memory of the computer. The single integer result is
output to standard output, followed by a newline.
<p>The integers to multiply may be specified on the command line
or read from standard input.</p>
<h2><a name='sect3' href='#toc3'>Author</a></h2>George Gesslein
II (gesslein@mathomatic.org) at "<a href=
'http://www.mathomatic.org'>http://www.mathomatic.org</a> ".
<h2><a name='sect4' href='#toc4'>Reporting Bugs</a></h2>If you
find a bug, please report it to the author or at "<a href=
'https://launchpad.net/mathomatic'>https://launchpad.net/mathomatic</a>
".
<h2><a name='sect5' href='#toc5'>See Also</a></h2><a href=
'mathomatic.1.html'><b>mathomatic</b>(1)</a> , <a href=
'primorial.1.html'><b>primorial</b>(1)</a> , <a href=
'matho-sum.1.html'><b>matho-sum</b>(1)</a>
<hr>
<p><a name='toc'><b>Table of Contents</b></a></p>
<ul>
<li><a name='toc0' href='#sect0'>Name</a></li>
<li><a name='toc1' href='#sect1'>Synopsis</a></li>
<li><a name='toc2' href='#sect2'>Description</a></li>
<li><a name='toc3' href='#sect3'>Author</a></li>
<li><a name='toc4' href='#sect4'>Reporting Bugs</a></li>
<li><a name='toc5' href='#sect5'>See Also</a></li>
</ul>
</body>
</html>

73
doc/matho-pascal.1.html Normal file
View File

@ -0,0 +1,73 @@
<!-- manual page source format generated by PolyglotMan v3.2, -->
<!-- available at http://polyglotman.sourceforge.net/ -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux (vers 25 March 2009), see www.w3.org">
<title>MATHO-PASCAL(1) manual page</title>
</head>
<body bgcolor='white'>
<a href='#toc'>Table of Contents</a>
<h2><a name='sect0' href='#toc0' id=
"sect0">Name</a></h2>matho-pascal - display Pascal&rsquo;s
triangle
<h2><a name='sect1' href='#toc1' id=
"sect1">Synopsis</a></h2><b>matho-pascal</b> [number-of-lines]
<h2><a name='sect2' href='#toc2' id=
"sect2">Description</a></h2>This command-line utility is
optionally part of the <a href=
'mathomatic.1.html'><b>mathomatic</b>(1)</a> package. It
calculates up to 1000 lines of Pascal&rsquo;s triangle using
floating point arithmetic, dumping the lines to standard output.
The default is to center one screen full.
<p>Every number inside Pascal&rsquo;s triangle is the sum of the
two numbers immediately above it.</p>
<p>Each line of Pascal&rsquo;s triangle is the same as the
binomial coefficients for a given power.</p>
<p>The sum of all numbers in each line of Pascal&rsquo;s triangle
is a power of 2.</p>
<h2><a name='sect3' href='#toc3' id="sect3">Author</a></h2>George
Gesslein II (gesslein@mathomatic.org) at "<a href=
'http://www.mathomatic.org'>http://www.mathomatic.org</a> ".
<h2><a name='sect4' href='#toc4' id="sect4">Reporting
Bugs</a></h2>If you find a bug, please report it to the author or
at "<a href=
'https://launchpad.net/mathomatic'>https://launchpad.net/mathomatic</a>
".
<h2><a name='sect5' href='#toc5' id="sect5">See
Also</a></h2><a href='mathomatic.1.html'><b>mathomatic</b>(1)</a>
, <a href='matho-primes.1.html'><b>matho-primes</b>(1)</a> ,
<a href='matho-sumsq.1.html'><b>matho-sumsq</b>(1)</a>
<hr>
<p><a name='toc' id="toc"><b>Table of Contents</b></a></p>
<ul>
<li><a name='toc0' href='#sect0' id="toc0">Name</a></li>
<li><a name='toc1' href='#sect1' id="toc1">Synopsis</a></li>
<li><a name='toc2' href='#sect2' id="toc2">Description</a></li>
<li><a name='toc3' href='#sect3' id="toc3">Author</a></li>
<li><a name='toc4' href='#sect4' id="toc4">Reporting
Bugs</a></li>
<li><a name='toc5' href='#sect5' id="toc5">See Also</a></li>
</ul>
</body>
</html>

126
doc/matho-primes.1.html Normal file
View File

@ -0,0 +1,126 @@
<!-- manual page source format generated by PolyglotMan v3.2, -->
<!-- available at http://polyglotman.sourceforge.net/ -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux (vers 25 March 2009), see www.w3.org">
<title>MATHO-PRIMES(1) manual page</title>
</head>
<body bgcolor='white'>
<a href='#toc'>Table of Contents</a>
<h2><a name='sect0' href='#toc0'>Name</a></h2>matho-primes -
generate consecutive prime numbers
<h2><a name='sect1' href=
'#toc1'>Synopsis</a></h2><b>matho-primes</b> [start [stop] or
"all"] ["twin"] ["pal" [base]]<br>
<b>matho-primes</b> [-htuv] [-c count] [-m number] [-p base]
[start [stop]]
<h2><a name='sect2' href='#toc2'>Description</a></h2>This
command-line utility is optionally part of the <a href=
'mathomatic.1.html'><b>mathomatic</b>(1)</a> package. It quickly
computes any number of consecutive prime numbers using a
windowing, memory efficient sieve of Eratosthenes algorithm,
dumping them to standard output. They are displayed one prime per
line in ascending order, unless the "twin" option is specified,
which displays only twin primes, two primes per line.
<p>Generates up to 18 decimal digit primes, or whatever is the
number of digits of precision for a floating point <b>long
double</b> in the C compiler used to compile this utility. Note
that this utility might be compiled to use only double precision
floating point, if long double precision is not fully supported
by the C compiler or hardware, allowing at most 15 decimal digit
primes in that case.</p>
<p>Ways to verify that this utility is working are to pipe the
output into the Unix "factor" utility, or compare the output with
the BSD Games "primes" utility, using the supplied shell script:
<b>examples/testprimes.</b></p>
<p>All numbers displayed by this utility are decimal (base 10)
prime numbers. A prime number is an integer that cannot be
factored.</p>
<p>A range may be specified on the command line, otherwise the
starting number and the number of primes to output is prompted
for. The range is <b>start</b> to <b>stop</b> inclusive, and
<b>stop</b> must be greater than or equal to <b>start.</b></p>
<p>If the <b>-c</b> option is specified, the number of lines of
primes displayed is limited to the decimal count that follows
this option.</p>
<p>If the <b>-t</b> or "twin" option is specified on the command
line, only <b>twin primes</b> will be displayed. Twin primes are
two primes that differ in value by 2. Each twin pair is displayed
together on the same line separated by a space character.</p>
<p>If the <b>-p</b> or "pal" option is specified on the command
line, only <b>palindromic primes</b> are displayed. Palindromes
are symmetrical, they read exactly the same forward and backward.
The palindromic number <b>base</b> may be specified, the default
is base 10. The <b>base</b> can be any integer greater than 1.
Primes are always displayed in decimal (base 10).</p>
<p>The version number and short help on the allowed command-line
parameters and usage information are displayed when given the
<b>-h</b> option.</p>
<p>With the <b>-u</b> option, all output (standard output and
standard error output) is set to be unbuffered, making all output
happen immediately, instead of when the output buffer is full or
when the program terminates or waits for input.</p>
<p>The <b>-m</b> option changes the memory size of the prime
number sieve window. It is followed by a decimal, floating point
number which is a multiplier of the default window size (2
megabytes). It is possible that changing the memory size may
speed up the total run time a bit; otherwise there is no reason
to use this option, and its use is not recommended.</p>
<p>The <b>-v</b> option simply displays the program name and
version number, and then exits successfully.</p>
<h2><a name='sect3' href='#toc3'>Author</a></h2>George Gesslein
II (gesslein@mathomatic.org) at "<a href=
'http://www.mathomatic.org'>http://www.mathomatic.org</a> ".
<h2><a name='sect4' href='#toc4'>Reporting Bugs</a></h2>If you
find a bug, please report it to the author or at "<a href=
'https://launchpad.net/mathomatic'>https://launchpad.net/mathomatic</a>
".
<h2><a name='sect5' href='#toc5'>See Also</a></h2><a href=
'rmath.1.html'><b>rmath</b>(1)</a> , <a href=
'mathomatic.1.html'><b>mathomatic</b>(1)</a> , <a href=
'primorial.1.html'><b>primorial</b>(1)</a> , <a href=
'matho-mult.1.html'><b>matho-mult</b>(1)</a> , <a href=
'matho-sum.1.html'><b>matho-sum</b>(1)</a> , <a href=
'matho-pascal.1.html'><b>matho-pascal</b>(1)</a> , <a href=
'matho-sumsq.1.html'><b>matho-sumsq</b>(1)</a>
<hr>
<p><a name='toc'><b>Table of Contents</b></a></p>
<ul>
<li><a name='toc0' href='#sect0'>Name</a></li>
<li><a name='toc1' href='#sect1'>Synopsis</a></li>
<li><a name='toc2' href='#sect2'>Description</a></li>
<li><a name='toc3' href='#sect3'>Author</a></li>
<li><a name='toc4' href='#sect4'>Reporting Bugs</a></li>
<li><a name='toc5' href='#sect5'>See Also</a></li>
</ul>
</body>
</html>

64
doc/matho-sum.1.html Normal file
View File

@ -0,0 +1,64 @@
<!-- manual page source format generated by PolyglotMan v3.2, -->
<!-- available at http://polyglotman.sourceforge.net/ -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux (vers 25 March 2009), see www.w3.org">
<title>MATHO-SUM(1) manual page</title>
</head>
<body bgcolor='white'>
<a href='#toc'>Table of Contents</a>
<h2><a name='sect0' href='#toc0'>Name</a></h2>matho-sum - sum
large integers
<h2><a name='sect1' href=
'#toc1'>Synopsis</a></h2><b>matho-sum</b> [integers]
<h2><a name='sect2' href='#toc2'>Description</a></h2>This
command-line utility is optionally part of the <a href=
'mathomatic.1.html'><b>mathomatic</b>(1)</a> package. It uses
Python to sum many large integers separated by spaces or
newlines. The size of the integers is only limited by the
available memory of the computer. The single integer result is
output to standard output, followed by a newline.
<p>The integers to sum may be specified on the command line or
read from standard input.</p>
<h2><a name='sect3' href='#toc3'>Author</a></h2>George Gesslein
II (gesslein@mathomatic.org) at "<a href=
'http://www.mathomatic.org'>http://www.mathomatic.org</a> ".
<h2><a name='sect4' href='#toc4'>Reporting Bugs</a></h2>If you
find a bug, please report it to the author or at "<a href=
'https://launchpad.net/mathomatic'>https://launchpad.net/mathomatic</a>
".
<h2><a name='sect5' href='#toc5'>See Also</a></h2><a href=
'mathomatic.1.html'><b>mathomatic</b>(1)</a> , <a href=
'primorial.1.html'><b>primorial</b>(1)</a> , <a href=
'matho-mult.1.html'><b>matho-mult</b>(1)</a>
<hr>
<p><a name='toc'><b>Table of Contents</b></a></p>
<ul>
<li><a name='toc0' href='#sect0'>Name</a></li>
<li><a name='toc1' href='#sect1'>Synopsis</a></li>
<li><a name='toc2' href='#sect2'>Description</a></li>
<li><a name='toc3' href='#sect3'>Author</a></li>
<li><a name='toc4' href='#sect4'>Reporting Bugs</a></li>
<li><a name='toc5' href='#sect5'>See Also</a></li>
</ul>
</body>
</html>

73
doc/matho-sumsq.1.html Normal file
View File

@ -0,0 +1,73 @@
<!-- manual page source format generated by PolyglotMan v3.2, -->
<!-- available at http://polyglotman.sourceforge.net/ -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux (vers 25 March 2009), see www.w3.org">
<title>MATHO-SUMSQ(1) manual page</title>
</head>
<body bgcolor='white'>
<a href='#toc'>Table of Contents</a>
<h2><a name='sect0' href='#toc0'>Name</a></h2>matho-sumsq - Find
the minimum sum of the squares for integers
<h2><a name='sect1' href=
'#toc1'>Synopsis</a></h2><b>matho-sumsq</b> [<i>numbers</i>]
<h2><a name='sect2' href='#toc2'>Description</a></h2>This
command-line utility is optionally part of the <a href=
'mathomatic.1.html'><b>mathomatic</b>(1)</a> package. It finds
the minimum number of positive integers that when squared and
added together, equal the given number. There is a proof that no
more than 4 squares summed together are required to represent any
positive integer.
<p>The command-line may contain positive integers to find the
minimum squares of, they must be less than 2147483648 (2^31) on
32-bit systems or less than 9223372036854775808 (2^63) on 64-bit
systems. If "+" is appended to the given number, the program
counts up from the given number. If the minimum number of squares
is 2, this program displays all possible combinations with 2
squares for the given number, otherwise it just displays the
first combination it finds.</p>
<p>If no command-line arguments are given, the programs reads the
numbers from standard input.</p>
<h2><a name='sect3' href='#toc3'>Author</a></h2>George Gesslein
II (gesslein@mathomatic.org) at "<a href=
'http://www.mathomatic.org'>http://www.mathomatic.org</a> ".
<h2><a name='sect4' href='#toc4'>Reporting Bugs</a></h2>If you
find a bug, please report it to the author or at "<a href=
'https://launchpad.net/mathomatic'>https://launchpad.net/mathomatic</a>
".
<h2><a name='sect5' href='#toc5'>See Also</a></h2><a href=
'mathomatic.1.html'><b>mathomatic</b>(1)</a> , <a href=
'matho-pascal.1.html'><b>matho-pascal</b>(1)</a> , <a href=
'matho-primes.1.html'><b>matho-primes</b>(1)</a>
<hr>
<p><a name='toc'><b>Table of Contents</b></a></p>
<ul>
<li><a name='toc0' href='#sect0'>Name</a></li>
<li><a name='toc1' href='#sect1'>Synopsis</a></li>
<li><a name='toc2' href='#sect2'>Description</a></li>
<li><a name='toc3' href='#sect3'>Author</a></li>
<li><a name='toc4' href='#sect4'>Reporting Bugs</a></li>
<li><a name='toc5' href='#sect5'>See Also</a></li>
</ul>
</body>
</html>

264
doc/mathomatic.1.html Normal file
View File

@ -0,0 +1,264 @@
<!-- manual page source format generated by PolyglotMan v3.2, -->
<!-- available at http://polyglotman.sourceforge.net/ -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux (vers 25 March 2009), see www.w3.org">
<title>MATHOMATIC(1) manual page</title>
</head>
<body bgcolor='white'>
<a href='#toc'>Table of Contents</a>
<h2><a name='sect0' href='#toc0' id=
"sect0">Name</a></h2>mathomatic - a computer algebra system
<h2><a name='sect1' href='#toc1' id=
"sect1">Synopsis</a></h2><b>mathomatic</b> [
<b>-abcdehqrtuvwx</b> ] [ <b>-s</b> level:time ] [ <b>-m</b>
number ] [ input_files or input ]
<h2><a name='sect2' href='#toc2' id=
"sect2">Description</a></h2>Mathomatic is a general-purpose
computer algebra system (CAS) that can symbolically solve,
simplify, combine, and compare algebraic equations, perform
standard, complex number, modular, and polynomial arithmetic,
etc. It does some calculus and handles all elementary algebra,
except logarithms. Trigonometry and function expansion are
supported in a separate program called <a href=
'rmath.1.html'><b>rmath</b>(1)</a> . Plotting expressions with
<b>gnuplot</b> is also supported.
<p><b>mathomatic</b> is the main Mathomatic application that does
interactive symbolic-numeric mathematics through a simple
command-line interface. Readline or editline support is usually
compiled into this application, making it easy to edit input and
recall previous input with the cursor keys. The numeric
arithmetic is double precision floating point with about 14
decimal digits accuracy. Many results will be exact, because
symbolic math is an exact math, and because multiple floating
point numbers can be combined for a single mathematical value;
for example: <b>2^(1/3),</b> which is the cube root of 2
exactly.</p>
<h2><a name='sect3' href='#toc3' id="sect3">Options</a></h2>
<dl>
<dt><b>-a</b></dt>
<dd>Enable alternative colors. Ansi color mode will be enabled
in MS-Windows, if this option is specified and color mode is
on.</dd>
<dt><b>-b</b></dt>
<dd>Enable bold colors. Color mode will be turned on and colors
will be brighter if this option is specified. Same as the "set
bold color" command.</dd>
<dt><b>-c</b></dt>
<dd>Toggle color mode. This mode outputs ANSI terminal escape
sequences to make each level of parentheses a different color,
for easier reading. Requires a terminal emulator that supports
ANSI color escape sequences. If the colors are too hard to see,
use the <b>-b</b> option to increase the color brightness.</dd>
<dt><b>-d</b></dt>
<dd>Set demo mode. Currently this mode only bypasses loading
the startup (rc) file, and ignores the pause command. It also
allows using the calculate command without prompting for the
values of any of the variables.</dd>
<dt><b>-e</b></dt>
<dd>Process mathematical expressions and Mathomatic commands
instead of input files on the shell command line, and then
quit. Unquoted space characters are the line separators on the
Mathomatic input that follows this option. Works similar to
entering it into the Mathomatic main prompt, except the
autoselect option is turned off. Useful for quick command-line
calculations. The startup messages are not displayed with this
option. Follow this option with "--" so that expressions can
start with a minus sign (-).</dd>
<dt><b>-h</b></dt>
<dd>Display a brief help message listing all of these options
and then exit.</dd>
<dt><b>-m number</b></dt>
<dd>Change the memory size of equation spaces. It is followed
by a decimal, floating point number which is a multiplier of
the default equation space size. This allows larger equation
spaces so that manipulating extremely large expressions will
succeed without getting the "Expression too large" error.
Specifying a number higher than 100 may make Mathomatic
unresponsive.</dd>
<dt><b>-q</b></dt>
<dd>Set quiet mode. The startup messages and prompts are not
displayed. This is useful when piping or redirecting input into
Mathomatic, because the input won&rsquo;t be displayed, so
prompt output should be turned off. This option does the same
thing as the "set no prompt" command.</dd>
<dt><b>-r</b></dt>
<dd>Disable readline or editline input processing. Readline,
and the editline drop-in replacement library, allow line input
editing using the cursor keys, and output terminal control
codes, all of which can be turned off with this option.</dd>
<dt><b>-s level:time</b></dt>
<dd>Set the enforced security level for the user&rsquo;s
Mathomatic session. Level 0 is the default with no security.
Level 1 disallows shelling out (forking). Level 2 disallows
shelling out and writing files. Level 3 disallows shelling out
and reading/writing files. Level 4 is the highest security
level and is the same as compiling with the -DSECURE option.
This run-time option was created for use on open public
servers. Specifying a colon, then a time in seconds, will time
limit the application for that session.</dd>
<dt><b>-t</b></dt>
<dd>Set test mode. Used when testing and comparing output.
Bypasses loading startup (rc) file, turns off color mode and
readline, sets wide output mode, ignores the pause command,
etc. It also allows using the calculate command without
prompting for the values of any of the variables.</dd>
<dt><b>-u</b></dt>
<dd>Guarantee that standard output and standard error output
are unbuffered. Also echoes all line input if not in quiet mode
( <b>-q</b> option ). Useful when piping.</dd>
<dt><b>-v</b></dt>
<dd>Display program name and version number, then exit
successfully.</dd>
<dt><b>-w</b></dt>
<dd>Set wide output mode for an unlimited width output device
like the "set wide" command does. Sets infinite screen columns
and rows so that 2D (two-dimensional) expression output will
always succeed and not be downgraded to 1D output when it
doesn&rsquo;t fit in the display area. Use when redirecting
output or with a terminal emulator that doesn&rsquo;t wrap
lines. This mode only affects 2D output.</dd>
<dt><b>-x</b></dt>
<dd>Enable HTML output mode (which is also valid XHTML). This
makes Mathomatic output suitable for inclusion in a web page.
Color and bold mode affect this mode, allowing HTML color
output. Wide output mode is also set by this option, meaning
expressions will always be displayed in 2D.</dd>
</dl>
<h2><a name='sect4' href='#toc4' id="sect4">General</a></h2>After
any options, text files may be specified on the shell command
line that will be automatically read in with the read command,
unless the <b>-e</b> option is specified.
<p>Mathomatic is best run from within a terminal emulator. It
uses console line input and output for the user interface. First
you type in your mathematical equations in standard algebraic
notation, then you can solve them by typing in the variable name
at the prompt, or perform operations on them with simple English
commands. Type "help" or "?" for the help command, "help
examples" to get started. If the command name is longer than 4
letters, you only need to type in the first 4 letters. Most
commands operate on the current equation by default.</p>
<p>A command preceded by an exclamation point (such as "!ls") is
taken to be a shell command and is passed unchanged to the shell
(/bin/sh). "!" by itself invokes the default shell, which is
specified in the SHELL environment variable. "!" is also the
factorial operator.</p>
<p>Complete documentation is available in HTML and PDF formats;
see the local documentation directory or online at "<a href=
'http://mathomatic.org/math/doc/'>http://mathomatic.org/math/doc/</a>
" for the latest Mathomatic documentation.</p>
<h2><a name='sect5' href='#toc5' id="sect5">Environment</a></h2>
<dl>
<dt><b>EDITOR</b></dt>
<dd>The EDITOR environment variable specifies which text editor
to use for the edit command.</dd>
</dl>
<h2><a name='sect6' href='#toc6' id="sect6">Files</a></h2>
<dl>
<dt><b>~/.mathomaticrc</b></dt>
<dd>Optional startup file containing Mathomatic set command
options. It should be a text file with one or more set options
per line. For example, the line "no color" will make Mathomatic
default to non-color mode, which is useful if you aren&rsquo;t
using a supported color device.</dd>
</dl>
<h2><a name='sect7' href='#toc7' id=
"sect7">Author</a></h2>Mathomatic has been written by George
Gesslein II (gesslein@mathomatic.org), with help from the
Internet community.
<h2><a name='sect8' href='#toc8' id="sect8">Reporting
Bugs</a></h2>The command to take the limit of an expression is
partially functional and experimental. All else should work
perfectly; if not, please report it as a bug to the author or on
the Launchpad website: "<a href=
'https://launchpad.net/mathomatic'>https://launchpad.net/mathomatic</a>
".
<h2><a name='sect9' href='#toc9' id="sect9">See
Also</a></h2><a href='rmath.1.html'><b>rmath</b>(1)</a> ,
<a href='matho-primes.1.html'><b>matho-primes</b>(1)</a> ,
<a href='primorial.1.html'><b>primorial</b>(1)</a> , <a href=
'matho-mult.1.html'><b>matho-mult</b>(1)</a> , <a href=
'matho-sum.1.html'><b>matho-sum</b>(1)</a> , <a href=
'matho-pascal.1.html'><b>matho-pascal</b>(1)</a> , <a href=
'matho-sumsq.1.html'><b>matho-sumsq</b>(1)</a>
<hr>
<p><a name='toc' id="toc"><b>Table of Contents</b></a></p>
<ul>
<li><a name='toc0' href='#sect0' id="toc0">Name</a></li>
<li><a name='toc1' href='#sect1' id="toc1">Synopsis</a></li>
<li><a name='toc2' href='#sect2' id="toc2">Description</a></li>
<li><a name='toc3' href='#sect3' id="toc3">Options</a></li>
<li><a name='toc4' href='#sect4' id="toc4">General</a></li>
<li><a name='toc5' href='#sect5' id="toc5">Environment</a></li>
<li><a name='toc6' href='#sect6' id="toc6">Files</a></li>
<li><a name='toc7' href='#sect7' id="toc7">Author</a></li>
<li><a name='toc8' href='#sect8' id="toc8">Reporting
Bugs</a></li>
<li><a name='toc9' href='#sect9' id="toc9">See Also</a></li>
</ul>
</body>
</html>

BIN
doc/mathomatic16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

BIN
doc/open_book_nae_02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

68
doc/primorial.1.html Normal file
View File

@ -0,0 +1,68 @@
<!-- manual page source format generated by PolyglotMan v3.2, -->
<!-- available at http://polyglotman.sourceforge.net/ -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux (vers 25 March 2009), see www.w3.org">
<title>PRIMORIAL(1) manual page</title>
</head>
<body bgcolor='white'>
<a href='#toc'>Table of Contents</a>
<h2><a name='sect0' href='#toc0'>Name</a></h2>primorial -
calculate large primorials
<h2><a name='sect1' href=
'#toc1'>Synopsis</a></h2><b>primorial</b> integers
<h2><a name='sect2' href='#toc2'>Description</a></h2>This
command-line utility is optionally part of the <a href=
'mathomatic.1.html'><b>mathomatic</b>(1)</a> package. It uses
Python and <a href=
'matho-primes.1.html'><b>matho-primes</b>(1)</a> and <a href=
'matho-mult.1.html'><b>matho-mult</b>(1)</a> to calculate and
display large primorials.
<p>A primorial is the product of all primes up to the given
integer. The integers to show the primorials of are given on the
command line.</p>
<p>The calculated primorials are output to standard output. The
size is limited by the amount of computer memory available.</p>
<h2><a name='sect3' href='#toc3'>Author</a></h2>George Gesslein
II (gesslein@mathomatic.org) at "<a href=
'http://www.mathomatic.org'>http://www.mathomatic.org</a> ".
<h2><a name='sect4' href='#toc4'>Reporting Bugs</a></h2>If you
find a bug, please report it to the author or at "<a href=
'https://launchpad.net/mathomatic'>https://launchpad.net/mathomatic</a>
".
<h2><a name='sect5' href='#toc5'>See Also</a></h2><a href=
'mathomatic.1.html'><b>mathomatic</b>(1)</a> , <a href=
'matho-mult.1.html'><b>matho-mult</b>(1)</a> , <a href=
'matho-primes.1.html'><b>matho-primes</b>(1)</a>
<hr>
<p><a name='toc'><b>Table of Contents</b></a></p>
<ul>
<li><a name='toc0' href='#sect0'>Name</a></li>
<li><a name='toc1' href='#sect1'>Synopsis</a></li>
<li><a name='toc2' href='#sect2'>Description</a></li>
<li><a name='toc3' href='#sect3'>Author</a></li>
<li><a name='toc4' href='#sect4'>Reporting Bugs</a></li>
<li><a name='toc5' href='#sect5'>See Also</a></li>
</ul>
</body>
</html>

239
doc/quickrefcard.html Normal file
View File

@ -0,0 +1,239 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 TRANSITIONAL//EN">
<html>
<head>
<title>Mathomatic Quick Reference Card</title>
</head>
<body>
<table cellpadding="4" border="3" summary="Mathomatic Quick Reference Card">
<tr bgcolor="#2648fe"><th colspan="3"><font color="white">Mathomatic version 16.0.5 Quick Reference Card</font></th></tr>
<tr>
<th>Command</th>
<th>Usage</th>
<th>Notes</th>
</tr>
<tr>
<td nowrap="nowrap">approximate</td>
<td nowrap="nowrap">approximate [equation-number-ranges]</td>
<td nowrap="nowrap">"repeat approximate" approximates more, like calculate.</td>
</tr>
<tr>
<td nowrap="nowrap">calculate</td>
<td nowrap="nowrap">calculate ["factor"] [equation-number-range] [variable iterations]</td>
<td nowrap="nowrap">"repeat calculate" repeatedly prompts for any input.</td>
</tr>
<tr>
<td nowrap="nowrap">clear</td>
<td nowrap="nowrap">clear [equation-number-ranges]</td>
<td nowrap="nowrap">Tip: Use "clear all" to quickly restart Mathomatic.</td>
</tr>
<tr>
<td nowrap="nowrap">code</td>
<td nowrap="nowrap">code ["c" or "java" or "python" or "integer"] [equation-number-ranges]</td>
<td nowrap="nowrap">Related commands: simplify, optimize, and variables</td>
</tr>
<tr>
<td nowrap="nowrap">compare</td>
<td nowrap="nowrap">compare ["symbolic" "approx"] equation-number ["with" equation-number]</td>
<td nowrap="nowrap">This command may be preceded with "repeat" for full simplify.</td>
</tr>
<tr>
<td nowrap="nowrap">copy</td>
<td nowrap="nowrap">copy ["select"] [equation-number-ranges]</td>
<td nowrap="nowrap">With select, the first copy is made the current equation.</td>
</tr>
<tr>
<td nowrap="nowrap">derivative</td>
<td nowrap="nowrap">derivative ["nosimplify"] variable or "all" [order]</td>
<td nowrap="nowrap">Alternate name for this command: differentiate</td>
</tr>
<tr>
<td nowrap="nowrap">display</td>
<td nowrap="nowrap">display ["factor"] ["simple" or "mixed"] [equation-number-ranges]</td>
<td nowrap="nowrap">Display expressions in pretty, 2D multi-line fraction format.</td>
</tr>
<tr>
<td nowrap="nowrap">divide</td>
<td nowrap="nowrap">divide [base-variable] [dividend divisor]</td>
<td nowrap="nowrap">"repeat divide" repeatedly prompts for any input.</td>
</tr>
<tr>
<td nowrap="nowrap">echo</td>
<td nowrap="nowrap">echo [text]</td>
<td nowrap="nowrap">This command may be preceded with "repeat".</td>
</tr>
<tr>
<td nowrap="nowrap">edit</td>
<td nowrap="nowrap">edit [file-name]</td>
<td nowrap="nowrap">Editor name in EDITOR environment variable.</td>
</tr>
<tr>
<td nowrap="nowrap">eliminate</td>
<td nowrap="nowrap">eliminate variables or "all" ["using" equation-number]</td>
<td nowrap="nowrap">This command may be preceded with "repeat".</td>
</tr>
<tr>
<td nowrap="nowrap">extrema</td>
<td nowrap="nowrap">extrema [variable] [order]</td>
<td nowrap="nowrap">Helps with finding the minimums and maximums.</td>
</tr>
<tr>
<td nowrap="nowrap">factor</td>
<td nowrap="nowrap">factor ["number" [integers]] or ["power"] [equation-number-range] [variables]</td>
<td nowrap="nowrap">Alternate name for this command: collect</td>
</tr>
<tr>
<td nowrap="nowrap">for</td>
<td nowrap="nowrap">for variable start end [step-size]</td>
<td nowrap="nowrap">Same syntax as the sum and product commands.</td>
</tr>
<tr>
<td nowrap="nowrap">fraction</td>
<td nowrap="nowrap">fraction ["numerator" "denominator"] [equation-number-range]</td>
<td nowrap="nowrap">This command may be preceded with "repeat".</td>
</tr>
<tr>
<td nowrap="nowrap">help</td>
<td nowrap="nowrap">help [topics or command-names]</td>
<td nowrap="nowrap">Alternate name for this command: ?</td>
</tr>
<tr>
<td nowrap="nowrap">imaginary</td>
<td nowrap="nowrap">imaginary [variable]</td>
<td nowrap="nowrap">Related command: real</td>
</tr>
<tr>
<td nowrap="nowrap">integrate</td>
<td nowrap="nowrap">integrate ["constant" or "definite"] variable [order [lower and upper-bounds]]</td>
<td nowrap="nowrap">Alternate name for this command: integral</td>
</tr>
<tr>
<td nowrap="nowrap">laplace</td>
<td nowrap="nowrap">laplace ["inverse"] variable</td>
<td nowrap="nowrap">This command only works with polynomials.</td>
</tr>
<tr>
<td nowrap="nowrap">limit</td>
<td nowrap="nowrap">limit variable expression</td>
<td nowrap="nowrap">This limit command is experimental.</td>
</tr>
<tr>
<td nowrap="nowrap">list</td>
<td nowrap="nowrap">list ["export" or "maxima" or "gnuplot" or "hex"] [equation-number-ranges]</td>
<td nowrap="nowrap">Options to export expressions to other math programs.</td>
</tr>
<tr>
<td nowrap="nowrap">nintegrate</td>
<td nowrap="nowrap">nintegrate ["trapezoid"] variable [partitions [lower and upper-bounds]]</td>
<td nowrap="nowrap">This command cannot integrate over singularities.</td>
</tr>
<tr>
<td nowrap="nowrap">optimize</td>
<td nowrap="nowrap">optimize [equation-number-range]</td>
<td nowrap="nowrap">Split up equations into smaller, more efficient equations.</td>
</tr>
<tr>
<td nowrap="nowrap">pause</td>
<td nowrap="nowrap">pause [text]</td>
<td nowrap="nowrap">Display a line of text and wait for user to press the Enter key.</td>
</tr>
<tr>
<td nowrap="nowrap">plot</td>
<td nowrap="nowrap">plot [equation-number-ranges] [xyz-ranges] [gnuplot-expressions,]</td>
<td nowrap="nowrap">Plots variable x; if expression contains y, do a 3D surface plot.</td>
</tr>
<tr>
<td nowrap="nowrap">product</td>
<td nowrap="nowrap">product variable start end [step-size]</td>
<td nowrap="nowrap">Related command: sum</td>
</tr>
<tr>
<td nowrap="nowrap">push</td>
<td nowrap="nowrap">push [equation-number-ranges or text-to-push]</td>
<td nowrap="nowrap">Available only if readline is enabled.</td>
</tr>
<tr>
<td nowrap="nowrap">quit</td>
<td nowrap="nowrap">quit [exit-value]</td>
<td nowrap="nowrap">Alternate name for this command: exit</td>
</tr>
<tr>
<td nowrap="nowrap">read</td>
<td nowrap="nowrap">read [file-name or directory]</td>
<td nowrap="nowrap">"repeat read" will read in a file repeatedly until failure.</td>
</tr>
<tr>
<td nowrap="nowrap">real</td>
<td nowrap="nowrap">real [variable]</td>
<td nowrap="nowrap">Related command: imaginary</td>
</tr>
<tr>
<td nowrap="nowrap">replace</td>
<td nowrap="nowrap">replace [variables ["with" expression]]</td>
<td nowrap="nowrap">This command may be preceded with "repeat".</td>
</tr>
<tr>
<td nowrap="nowrap">roots</td>
<td nowrap="nowrap">roots root real-part imaginary-part</td>
<td nowrap="nowrap">"repeat roots" repeatedly prompts for any input.</td>
</tr>
<tr>
<td nowrap="nowrap">save</td>
<td nowrap="nowrap">save file-name</td>
<td nowrap="nowrap">Related command: read</td>
</tr>
<tr>
<td nowrap="nowrap">set</td>
<td nowrap="nowrap">set [["no"] option [value]] ...</td>
<td nowrap="nowrap">"set" by itself will show all current option settings.</td>
</tr>
<tr>
<td nowrap="nowrap">simplify</td>
<td nowrap="nowrap">simplify ["sign" "symbolic" "quick[est]" "fraction"] [equation-number-ranges]</td>
<td nowrap="nowrap">This command may be preceded with "repeat" for full simplify.</td>
</tr>
<tr>
<td nowrap="nowrap">solve</td>
<td nowrap="nowrap">solve ["verify" or "verifiable"] [equation-number-range] ["for"] expression</td>
<td nowrap="nowrap">The verify options check all returned solutions for correctness.</td>
</tr>
<tr>
<td nowrap="nowrap">sum</td>
<td nowrap="nowrap">sum variable start end [step-size]</td>
<td nowrap="nowrap">Related command: product</td>
</tr>
<tr>
<td nowrap="nowrap">tally</td>
<td nowrap="nowrap">tally ["average"] [equation-number-ranges]</td>
<td nowrap="nowrap">Add entries, specified and prompted for, showing total.</td>
</tr>
<tr>
<td nowrap="nowrap">taylor</td>
<td nowrap="nowrap">taylor ["nosimplify"] variable order point</td>
<td nowrap="nowrap">Compute the Taylor series expansion of the current expression.</td>
</tr>
<tr>
<td nowrap="nowrap">unfactor</td>
<td nowrap="nowrap">unfactor ["count" "fraction" "quick" "power"] [equation-number-range]</td>
<td nowrap="nowrap">Alternate name for this command: expand</td>
</tr>
<tr>
<td nowrap="nowrap">variables</td>
<td nowrap="nowrap">variables ["c" "java" "integer" "count"] [equation-number-ranges]</td>
<td nowrap="nowrap">Related command: code</td>
</tr>
<tr>
<td nowrap="nowrap">version</td>
<td nowrap="nowrap">version ["status"]</td>
<td nowrap="nowrap">Display Mathomatic version, status, and compiler information.</td>
</tr>
</table>
<br clear=all>
<font size="+1">
Anything enclosed by straight brackets <b>[like this]</b> means it is optional and may be omitted.
</font>
<p>
<font size="+1">
<strong>For more information, visit <a href="http://www.mathomatic.org">www.mathomatic.org</a></strong>
</font>
</body>
</html>

152
doc/rmath.1.html Normal file
View File

@ -0,0 +1,152 @@
<!-- manual page source format generated by PolyglotMan v3.2, -->
<!-- available at http://polyglotman.sourceforge.net/ -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux (vers 25 March 2009), see www.w3.org">
<title>RMATH(1) manual page</title>
</head>
<body bgcolor='white'>
<a href='#toc'>Table of Contents</a>
<h2><a name='sect0' href='#toc0' id="sect0">Name</a></h2>rmath -
a computer algebra system with functions and readline<br>
matho - a computer algebra system with functions
<h2><a name='sect1' href='#toc1' id=
"sect1">Synopsis</a></h2><b>rmath</b> [ input_files ]<br>
<b>matho</b> [ input_files ]
<h2><a name='sect2' href='#toc2' id=
"sect2">Description</a></h2>Mathomatic is a general-purpose
computer algebra system (CAS) that can symbolically solve,
simplify, combine, and compare algebraic equations, perform
standard, complex number, modular, and polynomial arithmetic,
etc. It does some calculus and handles all elementary algebra,
except logarithms. Plotting expressions with <b>gnuplot</b> is
also supported.
<p><b>rmath</b> and <b>matho</b> are shell scripts that allow you
to use Mathomatic with input of functions like
<b>sin</b><i>(x)</i> and <b>sqrt</b><i>(x)</i> automatically
expanded to equivalent algebraic expressions by the <b>m4</b>
macro preprocessor. A matching pair of parentheses is required
around the parameters for all functions in m4 Mathomatic; m4
requires this. <b>rmath</b> also runs the <b>rlwrap</b> readline
wrapper utility if available, to provide readline input editing
support similar to that provided by <a href=
'mathomatic.1.html'><b>mathomatic</b>(1)</a> .</p>
<p><b>rmath</b> and <b>matho</b> define and enable named math
functions in Mathomatic. Most functions enabled here should be
real number, complex number, and symbolically capable. One
exception is the <b>abs</b><i>(x)</i> function, which
doesn&rsquo;t work with complex numbers, because it is defined in
Mathomatic as (((x)^2)^.5).</p>
<p>The following general functions are defined when using
<b>rmath</b> or <b>matho:</b> <b>sqrt</b><i>(x),</i>
<b>cbrt</b><i>(x),</i> <b>exp</b><i>(x),</i>
<b>pow</b><i>(x,y),</i> <b>abs</b><i>(x),</i>
<b>sgn</b><i>(x),</i> <b>factorial</b><i>(x),</i>
<b>gamma</b><i>(x),</i> <b>floor</b><i>(x),</i>
<b>ceil</b><i>(x),</i> <b>int</b><i>(x),</i> and
<b>round</b><i>(x).</i></p>
<p>The following standard trigonometric functions are defined:
<b>sin</b><i>(x),</i> <b>cos</b><i>(x),</i> <b>tan</b><i>(x),</i>
<b>cot</b><i>(x),</i> <b>sec</b><i>(x),</i> and
<b>csc</b><i>(x).</i> <b>sinc</b><i>(x)</i> is the normalized
sinc function, defined as
<b>sin</b><i>(pi*x)</i><b>/(pi*x)</b><i>.</i></p>
<p>The following standard hyperbolic trigonometric functions are
defined: <b>sinh</b><i>(x),</i> <b>cosh</b><i>(x),</i>
<b>tanh</b><i>(x),</i> <b>coth</b><i>(x),</i>
<b>sech</b><i>(x),</i> and <b>csch</b><i>(x).</i></p>
<p>The following universal constants are defined: <i>pi,</i>
<i>e,</i> <i>i</i> (the imaginary unit), <i>euler</i> (the
Euler-Mascheroni constant), <i>omega,</i> and <i>phi</i> (the
golden ratio).</p>
<h2><a name='sect3' href='#toc3' id="sect3">General</a></h2>Text
files may be specified on the shell command line that will be
automatically read in through the m4 preprocessor into
Mathomatic. After any files are read in, Mathomatic prompts for
input from the console.
<p>Mathomatic is best run from within a terminal emulator. It
uses console line input and output for the user interface. First
you type in your mathematical equations in standard algebraic
notation, then you can solve them by typing in the variable name
at the prompt, or perform operations on them with simple English
commands. Type "help" or "?" for the help command, "help
examples" to get started. If the command name is longer than 4
letters, you only need to type in the first 4 letters. Most
commands operate on the current equation by default.</p>
<p>Complete documentation is available in HTML and PDF formats;
see the local documentation directory or online at "<a href=
'http://mathomatic.org/math/doc/'>http://mathomatic.org/math/doc/</a>
" for the latest Mathomatic documentation.</p>
<h2><a name='sect4' href='#toc4' id="sect4">Files</a></h2>
<dl>
<dt><b>~/.mathomaticrc</b></dt>
<dd>Optional startup file containing Mathomatic set command
options. It should be a text file with one or more set options
per line. For example, the line "no color" will make Mathomatic
default to non-color mode, which is useful if you aren&rsquo;t
using a supported color device.</dd>
</dl>
<h2><a name='sect5' href='#toc5' id=
"sect5">Author</a></h2>Mathomatic has been written by George
Gesslein II (gesslein@mathomatic.org), with help from the
Internet community.
<h2><a name='sect6' href='#toc6' id="sect6">Reporting
Bugs</a></h2>Please report any bugs to the author or on the
Launchpad website: "<a href=
'https://launchpad.net/mathomatic'>https://launchpad.net/mathomatic</a>
".
<h2><a name='sect7' href='#toc7' id="sect7">See
Also</a></h2><a href='mathomatic.1.html'><b>mathomatic</b>(1)</a>
, <a href='matho-primes.1.html'><b>matho-primes</b>(1)</a> ,
<a href='primorial.1.html'><b>primorial</b>(1)</a> , <a href=
'matho-mult.1.html'><b>matho-mult</b>(1)</a> , <a href=
'matho-sum.1.html'><b>matho-sum</b>(1)</a> , <a href=
'matho-pascal.1.html'><b>matho-pascal</b>(1)</a> , <a href=
'matho-sumsq.1.html'><b>matho-sumsq</b>(1)</a>
<hr>
<p><a name='toc' id="toc"><b>Table of Contents</b></a></p>
<ul>
<li><a name='toc0' href='#sect0' id="toc0">Name</a></li>
<li><a name='toc1' href='#sect1' id="toc1">Synopsis</a></li>
<li><a name='toc2' href='#sect2' id="toc2">Description</a></li>
<li><a name='toc3' href='#sect3' id="toc3">General</a></li>
<li><a name='toc4' href='#sect4' id="toc4">Files</a></li>
<li><a name='toc5' href='#sect5' id="toc5">Author</a></li>
<li><a name='toc6' href='#sect6' id="toc6">Reporting
Bugs</a></li>
<li><a name='toc7' href='#sect7' id="toc7">See Also</a></li>
</ul>
</body>
</html>

41
examples/README.txt Normal file
View File

@ -0,0 +1,41 @@
examples/README.txt
-------------------
See directory ../tests for example, tutorial, and test scripts for
Mathomatic.
This directory is where example source code goes for a binary distribution.
-----------------------------------------------------------------------------
limits.c - C program to display current C data type limits and sizes.
Mathomatic is limited to double precision floating point.
Use "./compile.limits" to compile.
roots.c - Nice GSL example of a numerical polynomial equation solver utility.
Compile with "./c", requires the libgsl development files.
Like Mathomatic, uses complex number double precision output.
Use "./compile.roots" to compile.
testprimes - A parallel, brute force test of the prime number generator.
Checks the first 50,000,000 primes for gaps or errors.
Requires matho-primes and BSD Games primes to be installed.
It simply compares their output up to 1,000,000,000.
-----------------------------------------------------------------------------
This directory also contains factorial functions "factorial()" in various
computer languages are for use with output from the Mathomatic code command,
which converts factorial expressions like x! to factorial(x).
Type "./factorial" followed by integers or integer expressions to compute
large factorials with Python and test "fact.py".
-----------------------------------------------------------------------------
These files do not have any man page, because I think they are not ready or
are not made for packaging. They are just example programs. Any requests to
make man pages for these files will be honored by the author of this
document: George Gesslein II. Please specify which utilities you think should
be installable with a man page.

19
examples/compile.limits Executable file
View File

@ -0,0 +1,19 @@
#!/bin/sh
# Compile limits.c and create the executable in ~/bin if it exists.
# limits is a standalone program that nicely
# displays current C data type limits and sizes.
# Works with any C compiler, compiles with the C compiler you set CC to.
CC=${CC-cc}
if [ -d ~/bin ]
then
LIMITS=~/bin/limits
else
LIMITS=./limits
fi
echo Compiling limits.c
set -e
set -x
$CC -Wall $CFLAGS $CPPFLAGS $LDFLAGS -o $LIMITS limits.c
echo limits.c compiled and installed as $LIMITS

13
examples/compile.roots Executable file
View File

@ -0,0 +1,13 @@
#!/bin/sh
# Compile roots.c and create the executable in ~/bin if it exists.
# roots is a command-line numerical polynomial equation solver.
# Requires the GNU Scientific Library (GSL) development files.
if [ -d ~/bin ]
then
ROOTS=~/bin/roots
else
ROOTS=roots
fi
echo Compiling roots.c
gcc -O3 -Wall $CFLAGS $CPPFLAGS $LDFLAGS -o $ROOTS roots.c `pkg-config --cflags --libs gsl` && echo Done, executable installed in $ROOTS

39
examples/fact.c Normal file
View File

@ -0,0 +1,39 @@
#if 0
#define _REENTRANT 1 /* Should be defined before including math.h for Mac OS X. */
/* Do not use with iOS. Disabled by default and unnecessary. */
#endif
#include <math.h>
/*
* General factorial function in C for double precision floating point.
* Uses the threadsafe lgamma_r(3) function, if _REENTRANT is defined.
* Works for any floating point value.
* Recommend using tgamma(3) (true gamma) function instead, if available.
*
* Link with -lm
*
* Returns (arg!) (same as gamma(arg+1)).
* Sets "errno" external variable on overflow or error.
*/
double
factorial(double arg)
{
double d;
#if USE_TGAMMA
d = tgamma(arg + 1.0);
return d;
#else
#if _REENTRANT
int sign;
d = exp(lgamma_r(arg + 1.0, &sign));
return(d * sign);
#else
d = exp(lgamma(arg + 1.0)) * signgam;
return d;
#endif
#endif
}

20
examples/fact.py Normal file
View File

@ -0,0 +1,20 @@
# This is a general factorial function written in Python.
# A factorial is the product of all positive integers <= a given number.
# Works transparently with integers and floating point;
# that is, it returns the same type as its single argument.
# Gives an error for negative or non-integer input values.
def factorial(x):
"Return x! (x factorial)."
if (x < 0 or (x % 1.0) != 0.0):
raise ValueError, "Factorial argument must be a positive integer."
if (x == 0):
return x + 1
d = x
while (x > 2):
x -= 1
temp = d * x
if (temp <= d):
raise ValueError, "Factorial result too large."
d = temp
return d

30
examples/factorial Executable file
View File

@ -0,0 +1,30 @@
#!/usr/bin/python
# This is a Python program to display large factorials and test "fact.py".
from fact import factorial
import sys
import os
import string
def usage():
print "This program calculates large factorials."
print "Requires and tests \"fact.py\"."
print
print "Usage: %s integer_expressions" % os.path.basename(sys.argv[0])
print
print "The integer expressions should be separated by spaces."
print "A factorial is the product of all positive integers <= a given integer."
sys.exit(2)
args = sys.argv[1:]
if (args == []):
usage()
else:
try:
num = eval(string.join(args))
print "factorial(", num, ") =", factorial(num)
except:
for arg in args:
num = eval(arg)
print "factorial(", num, ") =", factorial(num)

20
examples/intfact.c Normal file
View File

@ -0,0 +1,20 @@
/*
* Factorial function in C for positive integers.
*
* Return (arg!).
* Returns -1 on error.
*/
int
factorial(int arg)
{
int result;
if (arg < 0)
return -1;
for (result = 1; result > 0 && arg > 1; arg--) {
result *= arg;
}
if (result <= 0) /* return -1 on overflow */
return -1;
return result;
}

161
examples/limits.c Normal file
View File

@ -0,0 +1,161 @@
/*
* Standalone program to nicely display current C data type limits and sizes.
*
* Copyright (C) 2008-2012 George Gesslein II
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
/*
* Compile with:
*
* cc limits.c -o limits
*
* then type "./limits".
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>
int
main(void)
{
float xf = 1.0;
double xd = 1.0;
#ifdef LDBL_EPSILON
long double xl = 1.0;
#endif
#ifdef __VERSION__
#ifdef __GNUC__
printf("GNU ");
#endif
printf("C Compiler version: %s\n\n", __VERSION__);
#endif
printf("C compiler integer limits:\n");
printf("--------------------------\n");
printf("CHAR_BIT: Bits of type char: %d\n", CHAR_BIT);
printf("sizeof(char) = %u bytes.\n", (unsigned) sizeof(char));
printf("sizeof(char *) = %u bytes.\n", (unsigned) sizeof(char *));
if (CHAR_MIN < 0) {
printf("Current type char is signed.\n");
} else {
printf("Current type char is unsigned.\n");
}
printf("CHAR_MAX: Maximum numeric value of type char: %d\n", CHAR_MAX);
printf("CHAR_MIN: Minimum numeric value of type char: %d\n\n", CHAR_MIN);
printf("SCHAR_MAX: Maximum value of type signed char: %d\n", SCHAR_MAX);
printf("SCHAR_MIN: Minimum value of type signed char: %d\n\n", SCHAR_MIN);
printf("UCHAR_MAX: Maximum value of type unsigned char: %u\n\n", (unsigned) UCHAR_MAX);
printf("sizeof(short) = %u bytes.\n", (unsigned) sizeof(short));
printf("SHRT_MAX: Maximum value of type short: %d\n", SHRT_MAX);
printf("SHRT_MIN: Minimum value of type short: %d\n\n", SHRT_MIN);
printf("USHRT_MAX: Maximum value of type unsigned short: %u\n\n", (unsigned) USHRT_MAX);
printf("sizeof(int) = %u bytes.\n", (unsigned) sizeof(int));
printf("INT_MAX: Maximum value of type int: %d\n", INT_MAX);
printf("INT_MIN: Minimum value of type int: %d\n\n", INT_MIN);
printf("UINT_MAX: Maximum value of type unsigned int: %u\n\n", UINT_MAX);
printf("sizeof(long) = %u bytes.\n", (unsigned) sizeof(long));
printf("LONG_MAX: Maximum value of type long: %ld\n", LONG_MAX);
printf("LONG_MIN: Minimum value of type long: %ld\n\n", LONG_MIN);
printf("ULONG_MAX: Maximum value of type unsigned long: %lu\n\n", ULONG_MAX);
#ifdef ULLONG_MAX
printf("sizeof(long long) = %u bytes.\n", (unsigned) sizeof(long long));
printf("LLONG_MAX: Maximum value of type long long: %lld\n", LLONG_MAX);
printf("LLONG_MIN: Minimum value of type long long: %lld\n\n", LLONG_MIN);
printf("ULLONG_MAX: Maximum value of type unsigned long long: %llu\n\n", ULLONG_MAX);
#else
printf("Type \"long long\" not supported by this C compiler.\n\n");
#endif
printf("\nC compiler floating point limits:\n");
printf("---------------------------------\n");
printf("sizeof(float) = %u bytes.\n", (unsigned) sizeof(float));
printf("FLT_DIG: Decimal digits of precision for float: %d\n", FLT_DIG);
printf("sizeof(double) = %u bytes.\n", (unsigned) sizeof(double));
printf("DBL_DIG: Decimal digits of precision for double: %d\n", DBL_DIG);
#ifdef LDBL_DIG
printf("sizeof(long double) = %u bytes.\n", (unsigned) sizeof(long double));
printf("LDBL_DIG: Decimal digits of precision for long double: %d\n", LDBL_DIG);
#endif
printf("\nFLT_MAX: Maximum value of float: %g\n", FLT_MAX);
printf("FLT_MIN: Minimum value of float: %g\n\n", FLT_MIN);
printf("DBL_MAX: Maximum value of double: %g\n", DBL_MAX);
printf("DBL_MIN: Minimum value of double: %g\n\n", DBL_MIN);
#ifdef LDBL_MAX
printf("LDBL_MAX: Maximum value of long double: %Lg\n", LDBL_MAX);
printf("LDBL_MIN: Minimum value of long double: %Lg\n\n", LDBL_MIN);
#else
printf("Type \"long double\" not supported by this C compiler.\n\n");
#endif
printf("Epsilon is the smallest x such that 1.0 + x != 1.0\n");
printf("FLT_EPSILON: Float epsilon: %g", FLT_EPSILON);
xf += (FLT_EPSILON / 2.0);
if (xf == 1.0) {
xf += FLT_EPSILON;
if (xf > 1.0) {
printf(" verified.");
}
}
printf("\n");
printf("DBL_EPSILON: Double epsilon: %g", DBL_EPSILON);
xd += (DBL_EPSILON / 2.0);
if (xd == 1.0) {
xd += DBL_EPSILON;
if (xd > 1.0) {
printf(" verified.");
}
}
printf("\n");
#ifdef LDBL_EPSILON
printf("LDBL_EPSILON: Long double epsilon: %Lg", LDBL_EPSILON);
xl += (LDBL_EPSILON / 2.0);
if (xl == 1.0) {
xl += LDBL_EPSILON;
if (xl > 1.0) {
printf(" verified.");
}
}
printf("\n");
#endif
printf("\nEnd of limits program output.\n");
return 0;
}

180
examples/roots.c Normal file
View File

@ -0,0 +1,180 @@
/*
* Command-line numerical polynomial equation solver using the GNU Scientific Library (GSL).
* GSL is available from: "http://www.gnu.org/software/gsl/".
*
* Copyright (C) 2008-2011 George Gesslein II
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
/*
* To compile:
./compile.roots
* or
gcc -O3 -Wall -o roots roots.c -lgsl -lgslcblas
* This program nicely solves any degree polynomial
* with real coefficients by calling the
* GSL function gsl_poly_complex_solve().
* This file is also useful for testing
* and as an example of using the GSL from C.
* The results are double precision floating point values
* that are sometimes accurate to 14 digits.
* Complex numbers are output if successful.
* Here is an example of it solving a cubic polynomial:
$ roots 1 1 1 1
The 3 approximate floating point solutions of:
+x^3 +x^2 +x +1 = 0
are:
x = +0 +1*i
x = +0 -1*i
x = -1
$
Try this for a large amount of error:
roots -1 -1 1 1
Proof the GSL isn't perfect.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <float.h>
#include <math.h>
#include <errno.h>
#include <gsl/gsl_poly.h>
#include <gsl/gsl_errno.h>
#define EPSILON 0.00000000000005 /* a good value for doubles */
#define HELP 1 /* display helpful text */
void display_root(int i);
char *prog_name = "roots"; /* name of this program */
double *a, *z; /* input and output arrays, respectively */
int precision = DBL_DIG - 1; /* display precision, it is not useful to set this higher than 15 */
void
usage(void)
{
printf("\n%s version 1.0 - numerical polynomial equation solver\n", prog_name);
printf("Uses the GNU Scientific Library (GSL).\n");
printf("\nSolves polynomial = 0 when given all real coefficients of the polynomial.\n");
printf("Double precision floating point math is used, accurate to about 14 digits.\n");
printf("\nUsage: %s highest-power-coefficient ... constant-term\n", prog_name);
printf("\nThe coefficients must be decimal, floating point, real numbers.\n");
printf("For example, if 4 real numbers are given, there will be 3 complex number\n");
printf("results or \"roots\" that are all valid solutions to polynomial = 0.\n");
}
int
main(int argc, char **argv)
{
int i, highest_power;
char *cp, *arg;
gsl_poly_complex_workspace *w;
if (argc <= 1) {
fprintf(stderr, "%s: The polynomial coefficients must be specified on the command line.\n", prog_name);
usage();
exit(2);
}
highest_power = argc - 2;
a = calloc(highest_power + 1, sizeof(double)); /* allocate real double input array */
z = calloc(2 * highest_power, sizeof(double)); /* allocate complex double output array */
/* parse the command line into the coefficient array a[] */
for (i = 0; i < argc - 1; i++) {
arg = argv[argc-i-1];
errno = 0;
a[i] = strtod(arg, &cp);
if (arg == cp || *cp) {
fprintf(stderr, "%s: Argument \"%s\" is not a floating point number.\n", prog_name, arg);
usage();
exit(2);
}
if (errno) {
fprintf(stderr, "%s: Argument \"%s\" is out of range.\n", prog_name, arg);
exit(2);
}
}
#if HELP
/* nicely display the actual polynomial equation we are solving */
printf("The %d approximate floating point solutions of:\n", highest_power);
for (i = highest_power; i >= 0; i--) {
if (a[i]) {
if (i && a[i] == 1.0) {
printf("+x");
} else {
printf("%+.*g", precision, a[i]);
if (i) {
printf("*x");
}
}
if (i > 1) {
printf("^%d", i);
}
printf(" ");
}
}
printf("= 0\nare:\n\n");
#endif
/* solve the polynomial equation */
w = gsl_poly_complex_workspace_alloc(highest_power + 1);
if (gsl_poly_complex_solve(a, highest_power + 1, w, z) != GSL_SUCCESS) {
fprintf(stderr, "%s: GSL approximation failed.\n", prog_name);
exit(1);
}
gsl_poly_complex_workspace_free(w);
/* display all solutions */
for (i = 0; i < highest_power; i++) {
#ifdef EPSILON /* zero out relatively very small values (which are floating point error) */
if (fabs(z[2*i] * EPSILON) > fabs(z[2*i+1]))
z[2*i+1] = 0.0;
else if (fabs(z[2*i+1] * EPSILON) > fabs(z[2*i]))
z[2*i] = 0.0;
#endif
#if HELP
printf("x = ");
#endif
display_root(i);
printf("\n");
}
exit(0);
}
void
display_root(int i)
{
printf("%+.*g", precision, z[2*i]); /* output real part */
if (z[2*i+1])
printf(" %+.*g*i", precision, z[2*i+1]); /* output imaginary part */
}

51
examples/testprimes Executable file
View File

@ -0,0 +1,51 @@
#!/bin/sh
# Test matho-primes by comparing output with the BSD Games primes utility.
# Only run this if matho-primes and the bsdgames package are installed.
# The comparison is performed in parallel, to save time.
# The whole test takes 30 seconds on a fast, dual-core computer.
#
# Checks the first 50,000,000 primes for gaps or errors.
# It simply compares their output up to 1,000,000,000.
#
# Usage: testprimes [ primes_utility_name ]
echo Testing matho-primes by comparing output with bsdgames primes...
if ! matho-primes 0 0
then
echo Mathomatic Prime Number Tools not installed.
echo Cannot find matho-primes
exit 1
fi
PRIMES=${1-primes}
if ! $PRIMES 0 0
then
PRIMES=/usr/games/primes
if $PRIMES 0 0
then
echo Using $PRIMES
else
echo bsdgames package not installed.
echo Cannot find primes utility.
exit 1
fi
fi
TESTOUT1=`mktemp /tmp/test.XXXXXXXXXX` || exit 1
TESTOUT2=`mktemp /tmp/test.XXXXXXXXXX` || exit 1
echo Starting and timing matho-primes
time -p matho-primes 1 1000000000 >$TESTOUT1 &
echo Starting $PRIMES
$PRIMES 1 1000000000 >$TESTOUT2 && echo -n Word count: && wc $TESTOUT2 &
wait
echo Output files to compare,
echo matho-primes output:
ls -l $TESTOUT1
echo primes output:
ls -l $TESTOUT2
echo Comparing:
diff -uq --strip-trailing-cr $TESTOUT1 $TESTOUT2 && echo Files are identical. && echo "Test passed 100% correctly." && rm $TESTOUT1 $TESTOUT2 && exit 0
echo
echo Test failed.
rm -f $TESTOUT1 $TESTOUT2
exit 1

136
externs.h Normal file
View File

@ -0,0 +1,136 @@
/*
* Mathomatic global variable extern definitions, from file "globals.c".
*
* Copyright (C) 1987-2012 George Gesslein II.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
extern int n_tokens;
extern int n_equations;
extern int cur_equation;
extern token_type *lhs[N_EQUATIONS];
extern token_type *rhs[N_EQUATIONS];
extern int n_lhs[N_EQUATIONS];
extern int n_rhs[N_EQUATIONS];
extern token_type *tlhs;
extern token_type *trhs;
extern token_type *tes;
extern int n_tlhs;
extern int n_trhs;
extern int n_tes;
extern token_type *scratch;
extern token_type zero_token;
extern token_type one_token;
extern int precision;
extern int case_sensitive_flag;
extern int factor_int_flag;
extern int display2d;
extern int fractions_display;
extern int approximate_roots;
extern int preserve_surds;
extern int rationalize_denominators;
extern int modulus_mode;
extern volatile int screen_columns;
extern volatile int screen_rows;
extern int finance_option;
extern int autosolve;
extern int autocalc;
extern int autodelete;
extern int autoselect;
extern char special_variable_characters[256];
extern char plot_prefix[256];
extern int factor_out_all_numeric_gcds;
extern int right_associative_power;
extern int power_starstar;
#if !SILENT
extern int debug_level;
#endif
extern int domain_check;
extern int color_flag;
extern int bold_colors;
extern int text_color;
extern int cur_color;
extern int html_flag;
extern int readline_enabled;
extern int partial_flag;
extern int symb_flag;
extern int symblify;
extern int high_prec;
extern int input_column;
extern int sign_cmp_flag;
extern double small_epsilon;
extern double epsilon;
extern char *prog_name;
extern char *var_names[MAX_VAR_NAMES];
extern char var_str[MAX_VAR_LEN+80];
extern char prompt_str[MAX_PROMPT_LEN];
#if !SECURE
extern char rc_file[MAX_CMD_LEN];
#endif
#if CYGWIN || MINGW
extern char *dir_path;
#endif
#if READLINE || EDITLINE
extern char *last_history_string;
#endif
#if READLINE
extern char *history_filename;
extern char history_filename_storage[MAX_CMD_LEN];
#endif
extern double unique[];
extern int ucnt[];
extern int uno;
extern int previous_return_value;
extern sign_array_type sign_array;
extern FILE *default_out;
extern FILE *gfp;
extern char *gfp_filename;
extern int gfp_append_flag;
extern jmp_buf jmp_save;
extern int eoption;
extern int test_mode;
extern int demo_mode;
extern int quiet_mode;
extern int echo_input;
extern volatile int abort_flag;
extern int pull_number;
extern int security_level;
extern int repeat_flag;
extern int show_usage;
extern int point_flag;
extern char *result_str;
extern int result_en;
extern const char *error_str;
extern const char *warning_str;
extern char *vscreen[TEXT_ROWS];
extern int current_columns;

1172
factor.c Normal file

File diff suppressed because it is too large Load Diff

568
factor_int.c Normal file
View File

@ -0,0 +1,568 @@
/*
* Mathomatic floating point constant factorizing routines.
*
* Copyright (C) 1987-2012 George Gesslein II.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
#include "includes.h"
static void try_factor(double arg);
static int fc_recurse(token_type *equation, int *np, int loc, int level, int level_code);
/* The following data is used to factor integers: */
static double nn, sqrt_value;
static double skip_multiples[] = { /* Additive array that skips over multiples of 2, 3, 5, and 7. */
10, 2, 4, 2, 4, 6, 2, 6,
4, 2, 4, 6, 6, 2, 6, 4,
2, 6, 4, 6, 8, 4, 2, 4,
2, 4, 8, 6, 4, 6, 2, 4,
6, 2, 6, 6, 4, 2, 4, 6,
2, 6, 4, 2, 4, 2,10, 2
}; /* sum of all numbers = 210 = (2*3*5*7) */
/*
* Factor the integer in "value".
* Store the prime factors in the unique[] array.
*
* Return true if successful.
*/
int
factor_one(value)
double value;
{
int i;
double d;
uno = 0;
nn = value;
if (nn == 0.0 || !isfinite(nn)) {
/* zero or not finite */
return false;
}
if (fabs(nn) >= MAX_K_INTEGER) {
/* too large to factor */
return false;
}
if (fmod(nn, 1.0) != 0.0) {
/* not an integer */
return false;
}
sqrt_value = 1.0 + sqrt(fabs(nn));
try_factor(2.0);
try_factor(3.0);
try_factor(5.0);
try_factor(7.0);
d = 1.0;
while (d <= sqrt_value) {
for (i = 0; i < ARR_CNT(skip_multiples); i++) {
d += skip_multiples[i];
try_factor(d);
}
}
if (nn != 1.0) {
if (nn < 0 && nn != -1.0) {
try_factor(fabs(nn));
}
try_factor(nn);
}
if (uno == 0) {
try_factor(1.0);
}
/* Do some floating point arithmetic self-checking. If the following fails, it is due to a floating point bug. */
if (nn != 1.0) {
error_bug("Internal error factoring integers (final nn != 1.0).");
}
if (value != multiply_out_unique()) {
error_bug("Internal error factoring integers (result array value is incorrect).");
}
return true;
}
/*
* See if "arg" is one or more factors of "nn".
* If so, save it and remove it from "nn".
*/
static void
try_factor(arg)
double arg;
{
#if DEBUG
if (fmod(arg, 1.0) != 0.0) {
error_bug("Trying factor that is not an integer!");
}
#endif
while (fmod(nn, arg) == 0.0) {
if (uno > 0 && ucnt[uno-1] > 0 && unique[uno-1] == arg) {
ucnt[uno-1]++;
} else {
while (uno > 0 && ucnt[uno-1] <= 0)
uno--;
unique[uno] = arg;
ucnt[uno++] = 1;
}
nn /= arg;
#if DEBUG
if (fmod(nn, 1.0) != 0.0) {
error_bug("nn turned non-integer in try_factor().");
}
#endif
sqrt_value = 1.0 + sqrt(fabs(nn));
if (fabs(nn) <= 1.5 || fabs(arg) <= 1.5)
break;
}
}
/*
* Convert unique[] back into the single integer it represents,
* which was the value passed in the last call to factor_one(value).
* Nothing is changed and the value is returned.
*/
double
multiply_out_unique(void)
{
int i, j;
double d;
d = 1.0;
for (i = 0; i < uno; i++) {
#if DEBUG
if (ucnt[i] < 0) {
error_bug("Error in ucnt[] being negative.");
}
#endif
for (j = 0; j < ucnt[i]; j++) {
d *= unique[i];
}
}
return d;
}
/*
* Display the integer prime factors in the unique[] array, even if mangled.
* Must have had a successful call to factor_one(value) previously,
* to fill out unique[] with the prime factors of value.
*
* Return true if successful.
*/
int
display_unique(void)
{
int i;
double value;
if (uno <= 0)
return false;
value = multiply_out_unique();
fprintf(gfp, "%.0f = ", value);
for (i = 0; i < uno;) {
if (ucnt[i] > 0) {
fprintf(gfp, "%.0f", unique[i]);
} else {
i++;
continue;
}
if (ucnt[i] > 1) {
fprintf(gfp, "^%d", ucnt[i]);
}
do {
i++;
} while (i < uno && ucnt[i] <= 0);
if (i < uno) {
fprintf(gfp, " * ");
}
}
fprintf(gfp, "\n");
return true;
}
/*
* Determine if the result of factor_one(x) is prime.
*
* Return true if x is a prime number.
*/
int
is_prime(void)
{
double value;
if (uno <= 0) {
#if DEBUG
error_bug("uno == 0 in is_prime().");
#endif
return false;
}
value = multiply_out_unique();
if (value < 2.0)
return false;
if (uno == 1 && ucnt[0] == 1)
return true;
return false;
}
/*
* Factor integers into their prime factors in an equation side.
*
* Return true if the equation side was modified.
*/
int
factor_int(equation, np)
token_type *equation;
int *np;
{
int i, j;
int xsize;
int level;
int modified = false;
for (i = 0; i < *np; i += 2) {
if (equation[i].kind == CONSTANT && factor_one(equation[i].token.constant) && uno > 0) {
if (uno == 1 && ucnt[0] <= 1)
continue; /* prime number */
level = equation[i].level;
if (uno > 1 && *np > 1)
level++;
xsize = -2;
for (j = 0; j < uno; j++) {
if (ucnt[j] > 1)
xsize += 4;
else
xsize += 2;
}
if (*np + xsize > n_tokens) {
error_huge();
}
for (j = 0; j < uno; j++) {
if (ucnt[j] > 1)
xsize = 4;
else
xsize = 2;
if (j == 0)
xsize -= 2;
if (xsize > 0) {
blt(&equation[i+xsize], &equation[i], (*np - i) * sizeof(token_type));
*np += xsize;
if (j > 0) {
i++;
equation[i].kind = OPERATOR;
equation[i].level = level;
equation[i].token.operatr = TIMES;
i++;
}
}
equation[i].kind = CONSTANT;
equation[i].level = level;
equation[i].token.constant = unique[j];
if (ucnt[j] > 1) {
equation[i].level = level + 1;
i++;
equation[i].kind = OPERATOR;
equation[i].level = level + 1;
equation[i].token.operatr = POWER;
i++;
equation[i].level = level + 1;
equation[i].kind = CONSTANT;
equation[i].token.constant = ucnt[j];
}
}
modified = true;
}
}
return modified;
}
/*
* Factor integers in an equation space.
*
* Return true if something was factored.
*/
int
factor_int_equation(n)
int n; /* equation space number */
{
int rv = false;
if (empty_equation_space(n))
return rv;
if (factor_int(lhs[n], &n_lhs[n]))
rv = true;
if (factor_int(rhs[n], &n_rhs[n]))
rv = true;
return rv;
}
/*
* List an equation side with optional integer factoring.
*/
int
list_factor(equation, np, factor_flag)
token_type *equation;
int *np;
int factor_flag;
{
if (factor_flag || factor_int_flag) {
factor_int(equation, np);
}
return list_proc(equation, *np, false);
}
/*
* Neatly factor out coefficients in additive expressions in an equation side.
* For example: (2*x + 4*y + 6) becomes 2*(x + 2*y + 3).
*
* This routine is often necessary because the expression compare (se_compare())
* does not return a multiplier (except for +/-1.0).
* Normalization done here is required for simplification of algebraic fractions, etc.
*
* If "level_code" is 0, all additive expressions are normalized
* by making at least one coefficient unity (1) by factoring out
* the absolute value of the constant coefficient closest to zero.
* This makes the absolute value of all other coefficients >= 1.
* If all coefficients are negative, -1 will be factored out, too.
*
* If "level_code" is 1, any level 1 additive expression is factored
* nicely for readability, while all deeper levels are normalized,
* so that algebraic fractions are simplified.
*
* If "level_code" is 2, nothing is normalized unless it increases
* readability.
*
* If "level_code" is 3, nothing is done.
*
* Add 4 to "level_code" to always factor out the GCD of rational coefficients
* to produce all reduced integer coefficients.
*
* Return true if equation side was modified.
*/
int
factor_constants(equation, np, level_code)
token_type *equation; /* pointer to the beginning of equation side */
int *np; /* pointer to length of equation side */
int level_code; /* see above */
{
if (level_code == 3)
return false;
return fc_recurse(equation, np, 0, 1, level_code);
}
static int
fc_recurse(equation, np, loc, level, level_code)
token_type *equation;
int *np, loc, level;
int level_code;
{
int i, j, k, eloc;
int op;
double d, minimum = 1.0, cogcd = 1.0;
int improve_readability, gcd_flag, first = true, neg_flag = true, modified = false;
int op_count = 0, const_count = 0;
for (i = loc; i < *np && equation[i].level >= level;) {
if (equation[i].level > level) {
modified |= fc_recurse(equation, np, i, level + 1, level_code);
i++;
for (; i < *np && equation[i].level > level; i += 2)
;
continue;
}
i++;
}
if (modified)
return true;
improve_readability = ((level_code & 3) > 1 || ((level_code & 3) && (level == 1)));
gcd_flag = ((improve_readability && factor_out_all_numeric_gcds) || (level_code & 4));
for (i = loc; i < *np && equation[i].level >= level;) {
if (equation[i].level == level) {
switch (equation[i].kind) {
case CONSTANT:
const_count++;
d = equation[i].token.constant;
break;
case OPERATOR:
switch (equation[i].token.operatr) {
case PLUS:
neg_flag = false;
case MINUS:
op_count++;
break;
default:
return modified;
}
i++;
continue;
default:
d = 1.0;
break;
}
if (i == loc && d > 0.0)
neg_flag = false;
d = fabs(d);
if (first) {
minimum = d;
cogcd = d;
first = false;
} else {
if (minimum > d)
minimum = d;
if (gcd_flag && cogcd != 0.0)
cogcd = gcd_verified(d, cogcd);
}
} else {
op = 0;
for (j = i + 1; j < *np && equation[j].level > level; j += 2) {
#if DEBUG
if (equation[j].kind != OPERATOR) {
error_bug("Bug in factor_constants().");
}
#endif
if (equation[j].level == level + 1) {
op = equation[j].token.operatr;
}
}
if (op == TIMES || op == DIVIDE) {
for (k = i; k < j; k++) {
if (equation[k].level == (level + 1) && equation[k].kind == CONSTANT) {
if (i == j)
return modified; /* more than one constant */
if (k > i && equation[k-1].token.operatr != TIMES)
return modified;
d = equation[k].token.constant;
if (i == loc && d > 0.0)
neg_flag = false;
d = fabs(d);
if (first) {
minimum = d;
cogcd = d;
first = false;
} else {
if (minimum > d)
minimum = d;
if (gcd_flag && cogcd != 0.0)
cogcd = gcd_verified(d, cogcd);
}
i = j;
}
}
if (i == j)
continue;
}
if (i == loc)
neg_flag = false;
if (first) {
minimum = 1.0;
cogcd = 1.0;
first = false;
} else {
if (minimum > 1.0)
minimum = 1.0;
if (gcd_flag && cogcd != 0.0)
cogcd = gcd_verified(1.0, cogcd);
}
i = j;
continue;
}
i++;
}
eloc = i;
if (gcd_flag && cogcd != 0.0 /* && fmod(cogcd, 1.0) == 0.0 */) {
minimum = cogcd;
}
if (first || op_count == 0 || const_count > 1 || (!neg_flag && minimum == 1.0))
return modified;
if (minimum == 0.0 || !isfinite(minimum))
return modified;
if (improve_readability) {
for (i = loc; i < eloc;) {
d = 1.0;
if (equation[i].kind == CONSTANT) {
if (equation[i].level == level || ((i + 1) < eloc
&& equation[i].level == (level + 1)
&& equation[i+1].level == (level + 1)
&& (equation[i+1].token.operatr == TIMES
|| equation[i+1].token.operatr == DIVIDE))) {
d = equation[i].token.constant;
}
}
#if 0 /* was 1; changed to 0 for optimal results and so 180*(sides-2) simplification works nicely. */
if (!gcd_flag && minimum >= 1.0) {
minimum = 1.0;
break;
}
#endif
#if 1
if ((minimum < 1.0) && (fmod(d, 1.0) == 0.0)) {
minimum = 1.0;
break;
}
#endif
/* Make sure division by the number to factor out results in an integer: */
if (fmod(d, minimum) != 0.0) {
minimum = 1.0; /* result not an integer */
break;
}
i++;
for (; i < *np && equation[i].level > level; i += 2)
;
if (i >= *np || equation[i].level < level)
break;
i++;
}
}
if (neg_flag)
minimum = -minimum;
if (minimum == 1.0)
return modified;
if (*np + ((op_count + 2) * 2) > n_tokens) {
error_huge();
}
for (i = loc; i < *np && equation[i].level >= level; i++) {
if (equation[i].kind != OPERATOR) {
for (j = i;;) {
equation[j].level++;
j++;
if (j >= *np || equation[j].level <= level)
break;
}
blt(&equation[j+2], &equation[j], (*np - j) * sizeof(token_type));
*np += 2;
equation[j].level = level + 1;
equation[j].kind = OPERATOR;
equation[j].token.operatr = DIVIDE;
j++;
equation[j].level = level + 1;
equation[j].kind = CONSTANT;
equation[j].token.constant = minimum;
i = j;
}
}
for (i = loc; i < *np && equation[i].level >= level; i++) {
equation[i].level++;
}
blt(&equation[i+2], &equation[i], (*np - i) * sizeof(token_type));
*np += 2;
equation[i].level = level;
equation[i].kind = OPERATOR;
equation[i].token.operatr = TIMES;
i++;
equation[i].level = level;
equation[i].kind = CONSTANT;
equation[i].token.constant = minimum;
return true;
}

468
gcd.c Normal file
View File

@ -0,0 +1,468 @@
/*
* General floating point GCD routine and associated code for Mathomatic.
* These routines are magically tuned to always give good results,
* even though floating point is used.
* Use of this code in other floating point programs that need a gcd() or
* double-to-fraction convert function is recommended.
* It is heavily tested through extensive use in this computer algebra system.
*
* Copyright (C) 1987-2012 George Gesslein II.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
#include "includes.h"
/*
* Floating point GCD function.
*
* Returns the Greatest Common Divisor (GCD) of doubles d1 and d2,
* by using the Euclidean GCD algorithm.
*
* The GCD is defined as the largest positive number that evenly divides both d1 and d2.
* This should always works perfectly and exactly with two integers up to MAX_K_INTEGER.
* Will usually work with non-integers, but there may be some floating point error.
*
* Returns 0 on failure, otherwise returns the positive GCD.
*/
double
gcd(d1, d2)
double d1, d2;
{
int count;
double larger, divisor, remainder1, lower_limit;
if (!isfinite(d1) || !isfinite(d2)) {
return 0.0; /* operands must be finite */
}
d1 = fabs(d1);
d2 = fabs(d2);
#if 1 /* true for standard gcd(), otherwise returns 0 (failure) if either parameter is 0 */
if (d1 == 0)
return d2;
if (d2 == 0)
return d1;
#endif
if (d1 > d2) {
larger = d1;
divisor = d2;
} else {
larger = d2;
divisor = d1;
}
lower_limit = larger * epsilon;
if (divisor <= lower_limit || larger >= MAX_K_INTEGER) {
return 0.0; /* out of range, result would be too inaccurate */
}
for (count = 1; count < 50; count++) {
remainder1 = fabs(fmod(larger, divisor));
if (remainder1 <= lower_limit || fabs(divisor - remainder1) <= lower_limit) {
if (remainder1 != 0.0 && divisor <= (100.0 * lower_limit))
return 0.0;
return divisor;
}
larger = divisor;
divisor = remainder1;
}
return 0.0;
}
/*
* Verified floating point GCD function.
*
* Returns the verified exact Greatest Common Divisor (GCD) of doubles d1 and d2.
*
* Returns 0 on failure or inexactness, otherwise returns the verified positive GCD result.
* Result is not necessarily integer unless both d1 and d2 are integer.
*/
double
gcd_verified(d1, d2)
double d1, d2;
{
double divisor, d3, d4;
divisor = gcd(d1, d2);
if (divisor != 0.0) {
d3 = d1 / divisor;
d4 = d2 / divisor;
if (fmod(d3, 1.0) != 0.0 || fmod(d4, 1.0) != 0.0)
return 0.0;
if (gcd(d3, d4) != 1.0)
return 0.0;
}
return divisor;
}
/*
* Floating point round function.
*
* Returns the passed floating point double rounded to the nearest integer.
*/
double
my_round(d1)
double d1; /* value to round */
{
if (d1 >= 0.0) {
modf(d1 + 0.5, &d1);
} else {
modf(d1 - 0.5, &d1);
}
return d1;
}
/*
* Convert the passed double d to an equivalent fully reduced fraction.
* This done by the following simple algorithm:
*
* divisor = gcd(d, 1.0)
* numerator = d / divisor
* denominator = 1.0 / divisor
*
* Returns true with integers in numerator and denominator
* if conversion to a fraction was successful.
* Otherwise returns false with numerator = d and denominator = 1.0
*
* True return indicates d is rational and finite, otherwise d is probably irrational.
*/
int
f_to_fraction(d, numeratorp, denominatorp)
double d; /* floating point number to convert */
double *numeratorp; /* returned numerator */
double *denominatorp; /* returned denominator */
{
double divisor;
double numerator, denominator;
double k3, k4;
*numeratorp = d;
*denominatorp = 1.0;
if (!isfinite(d)) {
return false;
}
/* see if "d" is an integer, or very close to an integer: */
if (fmod(d, 1.0) == 0.0) {
/* d is an integer */
return true;
}
/* more than 15 digits in number means we do nothing (for better accuracy) */
if (fabs(d) >= MAX_K_INTEGER)
return false;
k3 = fabs(d) * small_epsilon;
if (k3 >= .5)
return false; /* fixes "factor number 17!" to give error instead of wrong answer */
k4 = my_round(d);
if (k4 != 0.0 && fabs(k4 - d) <= k3) {
/* very close to an integer, make it so (allows gamma() based factorial function to work properly, etc.) */
*numeratorp = k4;
return true;
}
/* try to convert non-integer floating point value in "d" to a fraction: */
if ((divisor = gcd(1.0, d)) > epsilon) {
numerator = my_round(d / divisor);
denominator = my_round(1.0 / divisor);
/* don't allow more than 11 digits in the numerator or denominator: */
if (fabs(numerator) >= 1.0e12)
return false;
if (denominator >= 1.0e12 || denominator < 2.0)
return false;
/* make sure the result is a fully reduced fraction: */
divisor = gcd(numerator, denominator);
if (divisor > 1.0) { /* just in case result isn't already fully reduced */
numerator /= divisor;
denominator /= divisor;
}
k3 = (numerator / denominator);
if (fabs(k3 - d) > (small_epsilon * fabs(k3))) {
return false; /* result is too inaccurate */
}
if (fmod(numerator, 1.0) != 0.0 || fmod(denominator, 1.0) != 0.0) {
/* Shouldn't happen if everything works. */
#if DEBUG
error_bug("Fraction should have been fully reduced by gcd(), but was not.");
#endif
return false;
}
/* numerator and denominator are guaranteed integral */
*numeratorp = numerator;
*denominatorp = denominator;
return true;
}
return false;
}
/*
* Call make_simple_fractions() or make_mixed_fractions() below,
* depending on the current fractions display mode.
*
* Returns true if any fractions were created.
*/
int
make_fractions(equation, np)
token_type *equation; /* equation side pointer */
int *np; /* pointer to length of equation side */
{
switch (fractions_display) {
case 2:
return make_mixed_fractions(equation, np);
break;
default:
return make_simple_fractions(equation, np);
break;
}
}
/*
* Convert all non-integer constants in an equation side to simple, fully reduced fractions,
* when exactly equal to a fraction without a very large numerator or denominator.
* Uses f_to_fraction() above, which limits the numerator and denominator to 11 digits each.
* The floating point gcd() function used limits the complexity of fractions further.
*
* Returns true if any fractions were created.
*/
int
make_simple_fractions(equation, np)
token_type *equation; /* equation side pointer */
int *np; /* pointer to length of equation side */
{
int i, j, k;
int level;
double numerator, denominator;
int inc_level, modified = false;
for (i = 0; i < *np; i += 2) {
if (equation[i].kind == CONSTANT) {
level = equation[i].level;
if (i > 0 && equation[i-1].level == level && (equation[i-1].token.operatr == DIVIDE /* || equation[i-1].token.operatr == POWER */))
continue;
if (!f_to_fraction(equation[i].token.constant, &numerator, &denominator))
continue;
if (denominator == 1.0) {
equation[i].token.constant = numerator;
continue;
}
if ((*np + 2) > n_tokens) {
error_huge();
}
modified = true;
inc_level = (*np > 1);
if ((i + 1) < *np && equation[i+1].level == level) {
switch (equation[i+1].token.operatr) {
case TIMES:
for (j = i + 3; j < *np && equation[j].level >= level; j += 2) {
if (equation[j].level == level && equation[j].token.operatr == DIVIDE) {
break;
}
}
if (numerator == 1.0) {
blt(&equation[i], &equation[i+2], (j - (i + 2)) * sizeof(token_type));
j -= 2;
} else {
equation[i].token.constant = numerator;
blt(&equation[j+2], &equation[j], (*np - j) * sizeof(token_type));
*np += 2;
}
equation[j].level = level;
equation[j].kind = OPERATOR;
equation[j].token.operatr = DIVIDE;
j++;
equation[j].level = level;
equation[j].kind = CONSTANT;
equation[j].token.constant = denominator;
if (numerator == 1.0) {
i -= 2;
}
continue;
case DIVIDE:
inc_level = false;
break;
}
}
j = i;
blt(&equation[i+3], &equation[i+1], (*np - (i + 1)) * sizeof(token_type));
*np += 2;
equation[j].token.constant = numerator;
j++;
equation[j].level = level;
equation[j].kind = OPERATOR;
equation[j].token.operatr = DIVIDE;
j++;
equation[j].level = level;
equation[j].kind = CONSTANT;
equation[j].token.constant = denominator;
if (inc_level) {
for (k = i; k <= j; k++)
equation[k].level++;
}
}
}
return modified;
}
/*
* Convert all non-integer constants in an equation side to mixed, fully reduced fractions,
* when exactly equal to a fraction without a very large numerator or denominator.
* A mixed fraction is an expression like (2 + (1/4)),
* which is equal to the simple fraction 9/4.
* If you only want simple fractions, use make_simple_fractions() above.
*
* Returns true if any fractions were created.
*/
int
make_mixed_fractions(equation, np)
token_type *equation; /* equation side pointer */
int *np; /* pointer to length of equation side */
{
int i, j, k;
int level;
double numerator, denominator, quotient1, remainder1;
int inc_level, modified = false;
for (i = 0; i < *np; i += 2) {
if (equation[i].kind == CONSTANT) {
level = equation[i].level;
if (i > 0 && equation[i-1].level == level && (equation[i-1].token.operatr == DIVIDE /* || equation[i-1].token.operatr == POWER */))
continue;
if (!f_to_fraction(equation[i].token.constant, &numerator, &denominator))
continue;
if (denominator == 1.0) {
equation[i].token.constant = numerator;
continue;
}
modified = true;
if (fabs(numerator) > denominator) {
remainder1 = modf(fabs(numerator) / denominator, &quotient1);
remainder1 = my_round(remainder1 * denominator);
if (numerator < 0.0) {
if ((*np + 6) > n_tokens) {
error_huge();
}
blt(&equation[i+7], &equation[i+1], (*np - (i + 1)) * sizeof(token_type));
*np += 6;
equation[i].level = level + 1;
equation[i].token.constant = -1.0;
i++;
equation[i].level = level + 1;
equation[i].kind = OPERATOR;
equation[i].token.operatr = TIMES;
i++;
equation[i].level = level + 2;
equation[i].kind = CONSTANT;
equation[i].token.constant = quotient1;
i++;
equation[i].level = level + 2;
equation[i].kind = OPERATOR;
equation[i].token.operatr = PLUS;
i++;
equation[i].level = level + 3;
equation[i].kind = CONSTANT;
equation[i].token.constant = remainder1;
i++;
equation[i].level = level + 3;
equation[i].kind = OPERATOR;
equation[i].token.operatr = DIVIDE;
i++;
equation[i].level = level + 3;
equation[i].kind = CONSTANT;
equation[i].token.constant = denominator;
} else {
if ((*np + 4) > n_tokens) {
error_huge();
}
blt(&equation[i+5], &equation[i+1], (*np - (i + 1)) * sizeof(token_type));
*np += 4;
equation[i].level = level + 1;
equation[i].token.constant = quotient1;
i++;
equation[i].level = level + 1;
equation[i].kind = OPERATOR;
equation[i].token.operatr = PLUS;
i++;
equation[i].level = level + 2;
equation[i].kind = CONSTANT;
equation[i].token.constant = remainder1;
i++;
equation[i].level = level + 2;
equation[i].kind = OPERATOR;
equation[i].token.operatr = DIVIDE;
i++;
equation[i].level = level + 2;
equation[i].kind = CONSTANT;
equation[i].token.constant = denominator;
}
} else {
if ((*np + 2) > n_tokens) {
error_huge();
}
inc_level = (*np > 1);
if ((i + 1) < *np && equation[i+1].level == level) {
switch (equation[i+1].token.operatr) {
case TIMES:
for (j = i + 3; j < *np && equation[j].level >= level; j += 2) {
if (equation[j].level == level && equation[j].token.operatr == DIVIDE) {
break;
}
}
if (numerator == 1.0) {
blt(&equation[i], &equation[i+2], (j - (i + 2)) * sizeof(token_type));
j -= 2;
} else {
equation[i].token.constant = numerator;
blt(&equation[j+2], &equation[j], (*np - j) * sizeof(token_type));
*np += 2;
}
equation[j].level = level;
equation[j].kind = OPERATOR;
equation[j].token.operatr = DIVIDE;
j++;
equation[j].level = level;
equation[j].kind = CONSTANT;
equation[j].token.constant = denominator;
if (numerator == 1.0) {
i -= 2;
}
continue;
case DIVIDE:
inc_level = false;
break;
}
}
j = i;
blt(&equation[i+3], &equation[i+1], (*np - (i + 1)) * sizeof(token_type));
*np += 2;
equation[j].token.constant = numerator;
j++;
equation[j].level = level;
equation[j].kind = OPERATOR;
equation[j].token.operatr = DIVIDE;
j++;
equation[j].level = level;
equation[j].kind = CONSTANT;
equation[j].token.constant = denominator;
if (inc_level) {
for (k = i; k <= j; k++)
equation[k].level++;
}
}
}
}
if (modified) {
organize(equation, np);
}
return modified;
}

174
globals.c Normal file
View File

@ -0,0 +1,174 @@
/*
* Mathomatic global variables and arrays.
* Most global variables for Mathomatic are defined here and duplicated in "externs.h".
*
* C initializes global variables and arrays to zero by default.
* This is required for proper operation.
*
* Copyright (C) 1987-2012 George Gesslein II.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
#include "includes.h"
int n_tokens = DEFAULT_N_TOKENS; /* maximum size of expressions, must only be set during startup */
int n_equations, /* number of equation spaces allocated */
cur_equation; /* current equation space number (origin 0) */
/* expression storage pointers and current length variables (they go together) */
token_type *lhs[N_EQUATIONS], /* The Left Hand Sides of equation spaces */
*rhs[N_EQUATIONS]; /* The Right Hand Sides of equation spaces */
int n_lhs[N_EQUATIONS], /* number of tokens in each lhs[], 0 means equation space is empty */
n_rhs[N_EQUATIONS]; /* number of tokens in each rhs[], 0 means not an equation */
token_type *tlhs, /* LHS during solve and temporary storage for expressions, quotient for poly_div() and smart_div(). */
*trhs, /* RHS during solve and temporary storage for expressions, remainder for poly_div() and smart_div(). */
*tes, /* Temporary Equation Side, used in commands, simpa_repeat_side(), simple_frac_repeat_side(), etc. */
*scratch; /* Very temporary storage for expressions, used only in low level routines for expression manipulation. */
/* Do not run any functions on scratch[], except for blt() (which is memmove(3)). */
int n_tlhs, /* number of tokens in tlhs */
n_trhs, /* number of tokens in trhs */
n_tes; /* number of tokens in tes */
token_type zero_token, /* the universal constant 0.0 as an expression */
one_token; /* the universal constant 1.0 as an expression */
/* Set options with their initial values. */
int precision = 14; /* the display precision for doubles (number of digits) */
int case_sensitive_flag = true; /* "set case_sensitive" flag */
int factor_int_flag; /* factor integers when displaying expressions */
#if LIBRARY && !ROBOT_COMMAND
int display2d = false; /* "set no display2d" to allow feeding the output to the input */
#else
int display2d = true; /* "set display2d" flag for 2D display */
#endif
int fractions_display = 1; /* "set fraction" mode */
int preserve_surds = true; /* set option to preserve roots like (2^.5) */
int rationalize_denominators = true; /* try to rationalize denominators if true */
int modulus_mode = 2; /* true for mathematically correct modulus */
volatile int screen_columns = STANDARD_SCREEN_COLUMNS; /* screen width of the terminal; 0 = infinite */
volatile int screen_rows = STANDARD_SCREEN_ROWS; /* screen height of the terminal; 0 = infinite */
int finance_option = -1; /* for displaying dollars and cents */
int autosolve = true; /* Allows solving by typing the variable name at the main prompt */
int autocalc = true; /* Allows automatically calculating a numerical expression */
int autodelete = false; /* Automatically deletes the previous calculated numerical expression when a new one is entered */
int autoselect = true; /* Allows selecting equation spaces by typing the number */
#if LIBRARY
char special_variable_characters[256] = "\\[]"; /* allow backslash in variable names for Latex compatibility */
#else
char special_variable_characters[256] = "'\\[]"; /* user defined characters for variable names, '\0' terminated */
#endif
#if MINGW
char plot_prefix[256] = "set grid; set xlabel 'X'; set ylabel 'Y';"; /* prefix fed into gnuplot before the plot command */
#else
char plot_prefix[256] = "set grid; set xlabel \"X\"; set ylabel \"Y\";"; /* prefix fed into gnuplot before the plot command */
#endif
int factor_out_all_numeric_gcds = false; /* if true, factor out the GCD of rational coefficients */
int right_associative_power; /* if true, evaluate power operators right to left */
int power_starstar; /* if true, display power operator as "**", otherwise "^" */
#if !SILENT
int debug_level; /* current debug level */
#endif
/* variables having to do with color output mode */
#if LIBRARY || NO_COLOR
int color_flag = 0; /* library shouldn't default to color mode */
#else
int color_flag = 1; /* "set color" flag; 0 for no color, 1 for color, 2 for alternative color output mode */
#endif
#if BOLD_COLOR
int bold_colors = 1; /* "set bold color" flag for brighter colors */
#else
int bold_colors = 0; /* bold_colors must be 0 or 1; 0 is dim */
#endif
int text_color = -1; /* Current normal text color, -1 for no color */
int cur_color = -1; /* memory of current color on the terminal */
int html_flag; /* 1 for HTML mode on all standard output; 2 for HTML mode on all output, even redirected output */
/* double precision floating point epsilon constants for number comparisons for equivalency */
double small_epsilon = 0.000000000000005; /* for ignoring small, floating point round-off errors */
double epsilon = 0.00000000000005; /* for ignoring larger, accumulated round-off errors */
/* string variables */
char *prog_name = "mathomatic"; /* name of this program */
char *var_names[MAX_VAR_NAMES]; /* index for storage of variable name strings */
char var_str[MAX_VAR_LEN+80]; /* temp storage for listing a variable name */
char prompt_str[MAX_PROMPT_LEN]; /* temp storage for the prompt string */
#if !SECURE
char rc_file[MAX_CMD_LEN]; /* pathname for the set options startup file */
#endif
#if CYGWIN || MINGW
char *dir_path; /* directory path to the executable */
#endif
#if READLINE || EDITLINE
char *last_history_string; /* To prevent repeated, identical entries. Must not point to temporary string. */
#endif
#if READLINE
char *history_filename;
char history_filename_storage[MAX_CMD_LEN];
#endif
/* The following are for integer factoring (filled by factor_one()): */
double unique[64]; /* storage for the unique prime factors */
int ucnt[64]; /* number of times the factor occurs */
int uno; /* number of unique factors stored in unique[] */
/* misc. variables */
int previous_return_value = 1; /* Return value of last command entered. */
sign_array_type sign_array; /* for keeping track of unique "sign" variables */
FILE *default_out; /* file pointer where all gfp output goes by default */
FILE *gfp; /* global output file pointer, for dynamically redirecting Mathomatic output */
char *gfp_filename; /* filename associated with gfp if redirection is happening */
int gfp_append_flag; /* true if appending to gfp, false if overwriting */
jmp_buf jmp_save; /* for setjmp(3) to longjmp(3) to when an error happens deep within this code */
int eoption; /* -e option flag */
int test_mode; /* test mode flag (-t) */
int demo_mode; /* demo mode flag (-d), don't load rc file or pause commands when true */
int quiet_mode; /* quiet mode (-q, don't display prompts) */
int echo_input; /* if true, echo input */
int readline_enabled = true; /* set to false (-r) to disable readline */
int partial_flag; /* normally true for partial unfactoring, false for "unfactor fraction" */
int symb_flag; /* true during "simplify symbolic", which is not 100% mathematically correct */
int symblify = true; /* if true, set symb_flag when helpful during solving, etc. */
int high_prec; /* flag to output constants in higher precision (used when saving equations) */
int input_column; /* current column number on the screen at the beginning of a parse */
int sign_cmp_flag; /* true when all "sign" variables are to compare equal */
int domain_check; /* flag to track domain errors in the pow() function */
int approximate_roots; /* true if in calculate command (force approximation of roots like (2^.5)) */
volatile int abort_flag; /* if true, abort current operation; set by control-C interrupt */
int pull_number; /* equation space number to pull when using the library */
int security_level; /* current enforced security level for session, -1 for m4 Mathomatic */
int repeat_flag; /* true if the command is to repeat its function or simplification, set by repeat command */
int show_usage; /* show command usage info if a command fails and this flag is true */
int point_flag; /* point to location of parse error if true */
/* library variables go here */
char *result_str; /* returned result text string when using as library */
int result_en = -1; /* equation number of the returned result, if stored in an equation space */
const char *error_str; /* last error string */
const char *warning_str; /* last warning string */
/* Screen character array, for buffering page-at-a-time 2D string output: */
char *vscreen[TEXT_ROWS];
int current_columns;

1313
help.c Normal file

File diff suppressed because it is too large Load Diff

13
icons/README.txt Normal file
View File

@ -0,0 +1,13 @@
Mathomatic icons for your desktop go here.
icon.rc - Windows resource compiler file used to link icon with .exe file
mathomatic.desktop - Unix and Linux desktop entry
mathomatic.icns - Mathomatic icons for Mac OS X
mathomatic.ico - 32x32 and 64x64 pixels icons for Microsoft Windows
mathomatic.png - generic 64x64 Mathomatic icon
mathomatic.svg - The new resizeable Mathomatic logo and icon
mathomatic.xpm - X-Windows pixmap 32x32 Mathomatic icon
mathomatic32x32.png - generic 32x32 Mathomatic icon
These icons/logos are free to use for anything Mathomatic related.

12
icons/icon.rc Normal file
View File

@ -0,0 +1,12 @@
/*
* icon.rc - Windows resource compiler input file used to link
* the Mathomatic icon with the mathomatic.exe file.
*
* To compile, run:
*
* windres icon.rc icon.o
*
* then link mathomatic.exe with icon.o,
* so that mathomatic.exe will have an nice icon in Windows Explorer!
*/
icon1 ICON "mathomatic.ico"

10
icons/mathomatic.desktop Normal file
View File

@ -0,0 +1,10 @@
[Desktop Entry]
Name=Mathomatic
GenericName=Computer Algebra System
Comment=Do symbolic mathematics and quick calculations
Exec=mathomatic
Icon=mathomatic
Terminal=true
Type=Application
Categories=Education;Science;Math;
StartupNotify=false

BIN
icons/mathomatic.icns Normal file

Binary file not shown.

BIN
icons/mathomatic.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
icons/mathomatic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

130
icons/mathomatic.svg Normal file
View File

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="192"
height="195.14284"
id="svg2"
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="mathomatic.svg"
inkscape:export-filename="/home/george/mathomatic.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<title
id="title2985">Mathomatic Logo</title>
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="153.85714"
inkscape:cy="136.28578"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1600"
inkscape:window-height="816"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Mathomatic Logo</dc:title>
<dc:date>1/24/2012</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>George Gesslein II</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>Trademark for the Mathomatic computer algebra system</dc:title>
</cc:Agent>
</dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>George Gesslein II</dc:title>
</cc:Agent>
</dc:publisher>
<dc:language>en</dc:language>
<dc:subject>
<rdf:Bag>
<rdf:li>algebra logo Mathomatic</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:description>Made with Inkscape.</dc:description>
<dc:contributor>
<cc:Agent>
<dc:title>George Gesslein II</dc:title>
</cc:Agent>
</dc:contributor>
<dc:coverage>Rights are granted to use this image for anything related to Mathomatic, the computer algebra system.</dc:coverage>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-266.85715,-427.79077)">
<image
y="427.79077"
x="266.85715"
id="image3066"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAARBJREFU WIXFl0sWgzAIRcHTjblyl4aD1hNIQMin5A1R5IKIAYkIEJEgWUSEAAAIAOnBOcRHGuQNiNfPfjY2 6Xc2NttX3ntYwbkz4qUG1oLWgVtf+RxRAYtcyzAqz7cBsBSpwIhvA2AR85ISnW4v8Ovc1wXQFM2e v74H0vMN9cAjrS9mXo0K8CYONxt4CMCTNy80sUm4JqOYvqDNJPynZHWKfTmANZat5t5SgRQArQmL rcB0A1iZRLq+zI5i6wYY/f6l36YKaEqrwDKAqKJT8TCvJKk6lGaMY/5HJdx+Kj6e8/mO4AAASNpx OCC+zMwksb0JhwDqVW5mtdtega4eiGTa2w+vACu2Zg9IAGSs6TXQDQPJnMmPfQ/wAAAAAElFTkSu QmCC "
width="192"
height="192"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1" />
<path
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:1;stroke-opacity:1;stroke-dasharray:none"
d="m 437.14286,620.93361 -42.85715,-17.14286 -17.14285,-5.71428 -8.57143,-14.28572 -11.42857,-5.71428 0,0 c 0,0 -11.42857,20 -28.57143,28.57143 -17.14286,8.57143 0,0 -60,8.57143 l 91.42857,-20"
id="path3841"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.85714293;stroke-miterlimit:1;stroke-opacity:1;stroke-dasharray:none"
d="m 285.85714,618.6479 c 0,-1.57143 5.78572,-2.85715 12.85715,-2.85715 12.28612,0 16.88357,-3.40045 9.28571,-6.86807 -1.96429,-0.89649 3.17857,-0.88298 11.42857,0.03 9.96484,1.10277 15,0.61092 15,-1.46526 0,-1.71887 2.57143,-3.12524 5.71429,-3.12524 3.6853,0 5.71428,-1.90476 5.71428,-5.36444 0,-2.95045 1.92857,-6.96502 4.28572,-8.92127 2.35714,-1.95626 4.28571,-5.32797 4.28571,-7.4927 0,-3.14973 -7.74496,-3.93587 -38.77551,-3.93587 -29.79592,0 -39.72073,-0.94522 -42.85714,-4.08163 -6.01121,-6.01122 -6.01121,-134.39696 0,-140.40817 6.04667,-6.04667 171.50434,-6.04667 177.55102,0 6.01121,6.01121 6.01121,134.39695 0,140.40817 -3.13641,3.13641 -13.06123,4.08163 -42.85714,4.08163 -36.47775,0 -38.77551,0.32862 -38.77551,5.54566 0,3.05012 1.28571,6.34028 2.85714,7.31148 1.57143,0.9712 2.85714,4.26136 2.85714,7.31148 0,4.01061 1.97716,5.54566 7.14286,5.54566 3.92857,0 7.14286,1.28572 7.14286,2.85715 0,1.57142 5.14285,2.85714 11.42857,2.85714 6.28571,0 11.42857,1.28571 11.42857,2.85714 0,1.57143 5.14286,2.85714 11.42857,2.85714 6.28571,0 11.42857,1.28572 11.42857,2.85715 0,1.8315 -26.66666,2.85714 -74.28571,2.85714 -47.61905,0 -74.28572,-1.02564 -74.28572,-2.85714 z m 153.06123,-55.51021 c 5.97736,-5.97736 5.97736,-111.57366 0,-117.55102 -6.02699,-6.02699 -148.66689,-6.02699 -154.69388,0 -5.55079,5.5508 -6.00971,111.11248 -0.5102,117.35885 5.29856,6.01814 149.19994,6.19631 155.20408,0.19217 l 0,0 z"
id="path3892"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.3 KiB

42
icons/mathomatic.xpm Normal file
View File

@ -0,0 +1,42 @@
/* XPM */
static char *mathomatic[] = {
/* columns rows colors chars-per-pixel */
"32 32 4 1",
" c #000000",
". c #FFFF00",
"X c #0000BF",
"o c None",
/* pixels */
"o oo",
" o",
" ....XX...XXXXX.....XX...X o",
" ......XXX.XXXXX..XX..XXX.XX o",
" ..XX..X...XXXXX..XX..X...XX o",
" ..XX..X.XXXXXXX..XX..X.XXXX o",
" ......X...X.XXX.....XX...XX o",
" ......XXXXX.XXX..XX..XXXXXX o",
" ..XX..XXX.....X..XX..XXXXXX o",
" ..XX..XXXXX.XXX..XX..XXXXXX o",
" ..XX..XXXXX.XXX.....XXXXXXX o",
" XXXXXXXXXXXXXXXXXXXXXXXXXXX o",
" XXXXXXXXXXXXXXXXXXXXXXXX... o",
" XXXXXXXXXXXXXXXXXX.....XXX. o",
" XXXXXXXXXXXXXXXXXX.....X... o",
" XXXXXXXXXXXXXXXXXX..XXXX.XX o",
" XXXXXXXXXX......XX..XXXX... o",
" XXXXXXXXXXXXXXXXXX..XXXXXXX o",
" XXXXXXXXXX......XX..XXXXXXX o",
" XXXXXXXXXXXXXXXXXX..XXXXXXX o",
" XXXXXXXXXXXXXXXXXX.....XXXX o",
" XXXXXXXXXXXXXXXXXX.....XXXX o",
" XXXXXXXXXXXXXXXXXXXXXXXXX o",
" o",
"o oo",
"oooooooooooooo ooooooooooooooo",
"oooooooooooooo ooooooooooooooo",
"ooooooooooooo oooooooooooooo",
"ooooooooooooo oooooooooooooo",
"ooooooooooo oooooooooooo",
"ooooooo oooooooo",
"ooo oooo"
};

BIN
icons/mathomatic32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

119
includes.h Normal file
View File

@ -0,0 +1,119 @@
/*
* Standard C include files for Mathomatic.
* Automatically includes all necessary C include files for
* any Mathomatic C source code.
*
* Copyright (C) 1987-2012 George Gesslein II.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
#define true 1
#define false 0
#if 0
#define _REENTRANT 1 /* Can be defined before including math.h for Mac OS X. Mac OS X allows a few re-entrant functions with this. iOS requires this commented out. */
#endif
#if ROBOT_COMMAND
#define NOT80COLUMNS 1 /* For programs that use less than 80 columns wide display. */
#endif
#ifndef HELP
#define HELP 1 /* Define HELP=0 to remove the help command. Shaves at least 10 kilobytes off of the executable. */
#endif
#if LIBRARY /* If compiling this Mathomatic code as the symbolic math library: */
#ifndef SILENT /* Define SILENT=0 to have debugging enabled with the symbolic math library. */
#define SILENT 1 /* Disable debug level setting and stop messages going to stdout. */
#endif
#undef READLINE /* Readline shouldn't be included in the library code. */
#undef EDITLINE /* Editline neither */
#endif
#if __CYGWIN__ && !CYGWIN
#warning Compiling under Cygwin without proper defines.
#warning Please define CYGWIN on the compiler command line with -DCYGWIN
#define CYGWIN 1
#endif
#if CYGWIN || MINGW
#undef UNIX /* Unix desktop functionality is slightly different for CYGWIN and MINGW */
#endif
#if (UNIX || CYGWIN || MINGW) && !SECURE && !LIBRARY
#define SHELL_OUT 1 /* include the code to shell out (run system(3) commmand) */
#endif
#if SECURE && SHELL_OUT
#warning SHELL_OUT defined during secure mode compilation. This is a security problem.
#endif
/* Include files from /usr/include: */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#if UNIX
#include <libgen.h>
#endif
#if sun
#include <ieeefp.h>
#endif
#if SHOW_RESOURCES
#include <sys/time.h>
#include <sys/resource.h>
#endif
#include <limits.h>
#include <float.h>
#include <math.h>
#include <setjmp.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#if I18N /* Internationalization doesn't work yet. It would need a translation and some work on the code and makefile. */
#include <libintl.h> /* Mac OS X doesn't have libintl.h, so define "char *gettext();" then. */
#include <locale.h>
#endif
#if READLINE
#if 0 /* The following two includes only needed if explicitly calling ncurses functions. */
#include <curses.h>
#include <term.h>
#endif
#include <readline/readline.h>
#include <readline/history.h>
#endif
#if EDITLINE /* Editline is a stripped down version of readline. */
#include <editline.h>
#endif
/* Include files from the current directory: */
#include "standard.h" /* a standard include file for any math program written in C */
#include "am.h" /* the main include file for Mathomatic, contains tunable parameters */
#include "complex.h" /* floating point complex number arithmetic function prototypes */
#include "proto.h" /* global function prototypes, made with cproto utility */
#include "altproto.h" /* backup global function prototypes, in case of no proto.h */
#include "externs.h" /* global variable extern definitions */
#include "blt.h" /* blt() function definition */

995
integrate.c Normal file
View File

@ -0,0 +1,995 @@
/*
* Mathomatic integration routines and commands.
*
* Copyright (C) 1987-2012 George Gesslein II.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
#include "includes.h"
static int integrate_sub(token_type *equation, int *np, int loc, int eloc, long v);
static int laplace_sub(token_type *equation, int *np, int loc, int eloc, long v);
static int inv_laplace_sub(token_type *equation, int *np, int loc, int eloc, long v);
static int constant_var_number = 1; /* makes unique numbers for the constant of integration */
/*
* Make variable "v" always raised to a power,
* unless it is on the right side of a power operator.
*/
void
make_powers(equation, np, v)
token_type *equation; /* pointer to beginning of equation side */
int *np; /* pointer to length of equation side */
long v; /* Mathomatic variable */
{
int i;
int level;
for (i = 0; i < *np;) {
level = equation[i].level;
if (equation[i].kind == OPERATOR && equation[i].token.operatr == POWER) {
for (i += 2; i < *np && equation[i].level >= level; i += 2)
;
continue;
}
if (equation[i].kind == VARIABLE && equation[i].token.variable == v) {
if ((i + 1) >= *np || equation[i+1].token.operatr != POWER) {
if (*np + 2 > n_tokens) {
error_huge();
}
level++;
equation[i].level = level;
i++;
blt(&equation[i+2], &equation[i], (*np - i) * sizeof(token_type));
*np += 2;
equation[i].level = level;
equation[i].kind = OPERATOR;
equation[i].token.operatr = POWER;
i++;
equation[i].level = level;
equation[i].kind = CONSTANT;
equation[i].token.constant = 1.0;
}
}
i++;
}
}
/*
* Integration dispatch routine for polynomials.
* Handles the level 1 additive operators,
* sending each polynomial term to the specified integration function.
*
* Return true if successful.
*/
int
int_dispatch(equation, np, v, func)
token_type *equation; /* pointer to beginning of equation side to integrate */
int *np; /* pointer to length of equation side */
long v; /* integration variable */
int (*func)(token_type *equation, int *np, int loc, int eloc, long v); /* integration function to call for each term */
{
int i, j;
make_powers(equation, np, v);
for (j = 0, i = 1;; i += 2) {
if (i >= *np) {
return((*func)(equation, np, j, i, v));
}
if (equation[i].level == 1
&& (equation[i].token.operatr == PLUS || equation[i].token.operatr == MINUS)) {
if (!(*func)(equation, np, j, i, v)) {
return false;
}
for (i = j + 1;; i += 2) {
if (i >= *np) {
return true;
}
if (equation[i].level == 1) {
j = i + 1;
break;
}
}
}
}
return true;
}
/*
* Do the actual integration of a polynomial term.
*
* Return true if successful.
*/
static int
integrate_sub(equation, np, loc, eloc, v)
token_type *equation; /* pointer to beginning of equation side */
int *np; /* pointer to length of equation side */
int loc; /* beginning location of term */
int eloc; /* end location of term */
long v; /* variable of integration */
{
int i, j, k;
int len;
int level, vlevel, mlevel;
int count;
int div_flag;
level = min_level(&equation[loc], eloc - loc);
/* determine if the term is a polynomial term in "v" */
for (i = loc, count = 0; i < eloc; i += 2) {
if (equation[i].kind == VARIABLE && equation[i].token.variable == v) {
count++;
if (count > 1)
return false;
vlevel = equation[i].level;
if (vlevel == level || vlevel == (level + 1)) {
for (k = loc + 1; k < eloc; k += 2) {
if (equation[k].level == level) {
switch (equation[k].token.operatr) {
case DIVIDE:
case TIMES:
continue;
case POWER:
if (k == (i + 1))
continue;
default:
return false;
}
}
}
if (vlevel == (level + 1)) {
if ((i + 1) < eloc && equation[i+1].level == vlevel
&& equation[i+1].token.operatr == POWER) {
continue;
}
} else {
continue;
}
}
return false;
}
}
mlevel = level + 1;
for (j = loc; j < eloc; j++)
equation[j].level += 2;
for (i = loc; i < eloc; i += 2) {
if (equation[i].kind == VARIABLE && equation[i].token.variable == v) {
div_flag = (i > loc && equation[i-1].token.operatr == DIVIDE);
i++;
if (i >= eloc || equation[i].token.operatr != POWER)
return false;
level = equation[i].level;
i++;
if (div_flag) {
if (equation[i].level == level
&& equation[i].kind == CONSTANT
&& equation[i].token.constant == 1.0)
return false;
if (*np + 2 > n_tokens)
error_huge();
for (j = i; j < eloc && equation[j].level >= level; j++)
equation[j].level++;
equation[i-3].token.operatr = TIMES;
blt(&equation[i+2], &equation[i], (*np - i) * sizeof(token_type));
*np += 2;
eloc += 2;
equation[i].level = level + 1;
equation[i].kind = CONSTANT;
equation[i].token.constant = -1.0;
equation[i+1].level = level + 1;
equation[i+1].kind = OPERATOR;
equation[i+1].token.operatr = TIMES;
}
for (j = i; j < eloc && equation[j].level >= level; j++)
equation[j].level++;
len = j - i;
if (*np + len + 5 > n_tokens)
error_huge();
blt(&equation[j+2], &equation[j], (*np - j) * sizeof(token_type));
*np += 2;
eloc += 2;
len += 2;
level++;
equation[j].level = level;
equation[j].kind = OPERATOR;
equation[j].token.operatr = PLUS;
j++;
equation[j].level = level;
equation[j].kind = CONSTANT;
equation[j].token.constant = 1.0;
blt(&equation[eloc+len+1], &equation[eloc], (*np - eloc) * sizeof(token_type));
*np += len + 1;
equation[eloc].level = mlevel;
equation[eloc].kind = OPERATOR;
equation[eloc].token.operatr = DIVIDE;
blt(&equation[eloc+1], &equation[i], len * sizeof(token_type));
return true;
}
}
if (*np + 2 > n_tokens) {
error_huge();
}
blt(&equation[eloc+2], &equation[eloc], (*np - eloc) * sizeof(token_type));
*np += 2;
equation[eloc].level = mlevel;
equation[eloc].kind = OPERATOR;
equation[eloc].token.operatr = TIMES;
eloc++;
equation[eloc].level = mlevel;
equation[eloc].kind = VARIABLE;
equation[eloc].token.variable = v;
return true;
}
/*
* The integrate command.
*/
int
integrate_cmd(cp)
char *cp;
{
int i, j;
int len;
long v = 0;
token_type *source, *dest;
int n1, n2, *nps, *np;
int definite_flag = false, constant_flag = false, solved;
double integrate_order = 1.0;
char var_name_buf[MAX_VAR_LEN], *cp_start;
long l1;
cp_start = cp;
if (current_not_defined()) {
return false;
}
n_tlhs = 0;
n_trhs = 0;
solved = solved_equation(cur_equation);
i = next_espace();
for (;; cp = skip_param(cp)) {
if (strcmp_tospace(cp, "definite") == 0) {
definite_flag = true;
continue;
}
if (strcmp_tospace(cp, "constant") == 0) {
constant_flag = true;
continue;
}
break;
}
if (constant_flag && definite_flag) {
error(_("Conflicting options given."));
return false;
}
if (n_rhs[cur_equation]) {
if (!solved) {
warning(_("Not a solved equation."));
}
debug_string(0, _("Only the RHS will be transformed."));
source = rhs[cur_equation];
nps = &n_rhs[cur_equation];
dest = rhs[i];
np = &n_rhs[i];
} else {
source = lhs[cur_equation];
nps = &n_lhs[cur_equation];
dest = lhs[i];
np = &n_lhs[i];
}
if (*cp) {
if (isvarchar(*cp)) {
cp = parse_var2(&v, cp);
if (cp == NULL) {
return false;
}
}
if (*cp) {
integrate_order = strtod(cp, &cp);
}
if (!isfinite(integrate_order) || integrate_order <= 0 || fmod(integrate_order, 1.0) != 0.0) {
error(_("The order must be a positive integer."));
return false;
}
}
if (*cp) {
cp = skip_comma_space(cp);
input_column += (cp - cp_start);
cp = parse_expr(tlhs, &n_tlhs, cp, false);
if (cp == NULL || n_tlhs <= 0) {
return false;
}
}
if (*cp) {
cp_start = cp;
cp = skip_comma_space(cp);
input_column += (cp - cp_start);
cp = parse_expr(trhs, &n_trhs, cp, false);
if (cp == NULL || extra_characters(cp) || n_trhs <= 0) {
return false;
}
}
show_usage = false;
if (v == 0) {
if (!prompt_var(&v)) {
return false;
}
}
#if !SILENT
list_var(v, 0);
if (n_rhs[cur_equation]) {
fprintf(gfp, _("Integrating the RHS with respect to %s"), var_str);
} else {
fprintf(gfp, _("Integrating with respect to %s"), var_str);
}
if (integrate_order != 1.0) {
fprintf(gfp, _(" %.*g times"), precision, integrate_order);
}
fprintf(gfp, _(" and simplifying...\n"));
#endif
partial_flag = false;
uf_simp(source, nps);
partial_flag = true;
factorv(source, nps, v);
blt(dest, source, *nps * sizeof(token_type));
n1 = *nps;
for (l1 = 0; l1 < integrate_order; l1++) {
if (!int_dispatch(dest, &n1, v, integrate_sub)) {
error(_("Integration failed, not a polynomial."));
return false;
}
if (constant_flag) {
if (n1 + 2 > n_tokens) {
error_huge();
}
for (j = 0; j < n1; j++) {
dest[j].level++;
}
dest[n1].kind = OPERATOR;
dest[n1].level = 1;
dest[n1].token.operatr = PLUS;
n1++;
dest[n1].kind = VARIABLE;
dest[n1].level = 1;
snprintf(var_name_buf, sizeof(var_name_buf), "C_%d", constant_var_number);
if (parse_var(&dest[n1].token.variable, var_name_buf) == NULL) {
return false;
}
n1++;
constant_var_number++;
if (constant_var_number < 0) {
constant_var_number = 1;
}
}
simp_loop(dest, &n1);
}
if (definite_flag) {
if (n_tlhs == 0) {
my_strlcpy(prompt_str, _("Enter lower bound: "), sizeof(prompt_str));
if (!get_expr(tlhs, &n_tlhs)) {
return false;
}
}
if (n_trhs == 0) {
my_strlcpy(prompt_str, _("Enter upper bound: "), sizeof(prompt_str));
if (!get_expr(trhs, &n_trhs)) {
return false;
}
}
blt(scratch, dest, n1 * sizeof(token_type));
n2 = n1;
subst_var_with_exp(scratch, &n2, tlhs, n_tlhs, v);
subst_var_with_exp(dest, &n1, trhs, n_trhs, v);
if (n1 + 1 + n2 > n_tokens) {
error_huge();
}
for (j = 0; j < n1; j++) {
dest[j].level++;
}
for (j = 0; j < n2; j++) {
scratch[j].level++;
}
dest[n1].kind = OPERATOR;
dest[n1].level = 1;
dest[n1].token.operatr = MINUS;
n1++;
blt(&dest[n1], scratch, n2 * sizeof(token_type));
n1 += n2;
}
simpa_side(dest, &n1, false, false);
*np = n1;
if (n_rhs[cur_equation]) {
blt(lhs[i], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type));
n_lhs[i] = n_lhs[cur_equation];
if (solved && isvarchar('\'')) {
len = list_var(lhs[i][0].token.variable, 0);
for (l1 = 0; l1 < integrate_order && len > 0 && var_str[len-1] == '\''; l1++) {
var_str[--len] = '\0';
}
parse_var(&lhs[i][0].token.variable, var_str);
}
}
cur_equation = i;
return return_result(cur_equation);
}
/*
* Do the actual Laplace transformation of a polynomial term.
*
* Return true if successful.
*/
static int
laplace_sub(equation, np, loc, eloc, v)
token_type *equation;
int *np;
int loc, eloc;
long v;
{
int i, j, k;
int len;
int level, mlevel;
mlevel = min_level(&equation[loc], eloc - loc) + 1;
for (j = loc; j < eloc; j++)
equation[j].level += 2;
for (i = loc; i < eloc; i += 2) {
if (equation[i].kind == VARIABLE && equation[i].token.variable == v) {
i++;
if (i >= eloc || equation[i].token.operatr != POWER)
return false;
level = equation[i].level;
i++;
for (j = i; j < eloc && equation[j].level >= level; j++)
equation[j].level++;
len = j - i;
if (*np + len + 7 > n_tokens)
error_huge();
blt(&equation[j+4], &equation[j], (*np - j) * sizeof(token_type));
*np += 4;
eloc += 4;
level++;
equation[j].level = level;
equation[j].kind = OPERATOR;
equation[j].token.operatr = PLUS;
j++;
equation[j].level = level;
equation[j].kind = CONSTANT;
equation[j].token.constant = 1.0;
j++;
for (k = i; k < j; k++)
equation[k].level++;
equation[j].level = level;
equation[j].kind = OPERATOR;
equation[j].token.operatr = TIMES;
j++;
equation[j].level = level;
equation[j].kind = CONSTANT;
equation[j].token.constant = -1.0;
blt(&equation[eloc+len+3], &equation[eloc], (*np - eloc) * sizeof(token_type));
*np += len + 3;
k = eloc;
equation[k].level = mlevel;
equation[k].kind = OPERATOR;
equation[k].token.operatr = TIMES;
k++;
blt(&equation[k], &equation[i], len * sizeof(token_type));
k += len;
equation[k].level = mlevel + 1;
equation[k].kind = OPERATOR;
equation[k].token.operatr = FACTORIAL;
k++;
equation[k].level = mlevel + 1;
equation[k].kind = CONSTANT;
equation[k].token.constant = 1.0;
return true;
}
}
if (*np + 2 > n_tokens) {
error_huge();
}
blt(&equation[eloc+2], &equation[eloc], (*np - eloc) * sizeof(token_type));
*np += 2;
equation[eloc].level = mlevel;
equation[eloc].kind = OPERATOR;
equation[eloc].token.operatr = DIVIDE;
eloc++;
equation[eloc].level = mlevel;
equation[eloc].kind = VARIABLE;
equation[eloc].token.variable = v;
return true;
}
/*
* Do the actual inverse Laplace transformation of a polynomial term.
*
* Return true if successful.
*/
static int
inv_laplace_sub(equation, np, loc, eloc, v)
token_type *equation;
int *np;
int loc, eloc;
long v;
{
int i, j, k;
int len;
int level, mlevel;
mlevel = min_level(&equation[loc], eloc - loc) + 1;
for (j = loc; j < eloc; j++)
equation[j].level += 2;
for (i = loc; i < eloc; i += 2) {
if (equation[i].kind == VARIABLE && equation[i].token.variable == v) {
i++;
if (i >= eloc || equation[i].token.operatr != POWER)
return false;
if ((i - 2) <= loc || equation[i-2].token.operatr != DIVIDE)
return false;
level = equation[i].level;
i++;
for (j = i; j < eloc && equation[j].level >= level; j++)
equation[j].level++;
len = j - i;
if (*np + len + 7 > n_tokens)
error_huge();
equation[i-3].token.operatr = TIMES;
blt(&equation[j+2], &equation[j], (*np - j) * sizeof(token_type));
*np += 2;
eloc += 2;
len += 2;
level++;
equation[j].level = level;
equation[j].kind = OPERATOR;
equation[j].token.operatr = MINUS;
j++;
equation[j].level = level;
equation[j].kind = CONSTANT;
equation[j].token.constant = 1.0;
blt(&equation[eloc+len+3], &equation[eloc], (*np - eloc) * sizeof(token_type));
*np += len + 3;
k = eloc;
equation[k].level = mlevel;
equation[k].kind = OPERATOR;
equation[k].token.operatr = DIVIDE;
k++;
blt(&equation[k], &equation[i], len * sizeof(token_type));
k += len;
equation[k].level = mlevel + 1;
equation[k].kind = OPERATOR;
equation[k].token.operatr = FACTORIAL;
k++;
equation[k].level = mlevel + 1;
equation[k].kind = CONSTANT;
equation[k].token.constant = 1.0;
return true;
}
}
return false;
}
/*
* The laplace command.
*/
int
laplace_cmd(cp)
char *cp;
{
int i;
long v = 0;
int inverse_flag, solved;
token_type *source, *dest;
int n1, *nps, *np;
if (current_not_defined()) {
return false;
}
solved = solved_equation(cur_equation);
i = next_espace();
if (n_rhs[cur_equation]) {
if (!solved) {
warning(_("Not a solved equation."));
}
#if !SILENT
fprintf(gfp, _("Only the RHS will be transformed.\n"));
#endif
source = rhs[cur_equation];
nps = &n_rhs[cur_equation];
dest = rhs[i];
np = &n_rhs[i];
} else {
source = lhs[cur_equation];
nps = &n_lhs[cur_equation];
dest = lhs[i];
np = &n_lhs[i];
}
inverse_flag = (strcmp_tospace(cp, "inverse") == 0);
if (inverse_flag) {
cp = skip_param(cp);
}
if (*cp) {
cp = parse_var2(&v, cp);
if (cp == NULL) {
return false;
}
if (extra_characters(cp)) {
return false;
}
}
show_usage = false;
if (v == 0) {
if (!prompt_var(&v)) {
return false;
}
}
partial_flag = false;
uf_simp(source, nps);
partial_flag = true;
factorv(source, nps, v);
blt(dest, source, *nps * sizeof(token_type));
n1 = *nps;
if (inverse_flag) {
if (!poly_in_v(dest, n1, v, true) || !int_dispatch(dest, &n1, v, inv_laplace_sub)) {
error(_("Inverse Laplace transformation failed."));
return false;
}
} else {
if (!poly_in_v(dest, n1, v, false) || !int_dispatch(dest, &n1, v, laplace_sub)) {
error(_("Laplace transformation failed, not a polynomial."));
return false;
}
}
#if 1
simp_loop(dest, &n1);
#else
simpa_side(dest, &n1, false, false);
#endif
if (n_rhs[cur_equation]) {
blt(lhs[i], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type));
n_lhs[i] = n_lhs[cur_equation];
}
*np = n1;
cur_equation = i;
return return_result(cur_equation);
}
/*
* Numerical integrate command.
*/
int
nintegrate_cmd(cp)
char *cp;
{
long v = 0; /* Mathomatic variable */
int i, j, k, i1, i2;
int len;
int level;
int iterations = 1000; /* must be even */
int first_size = 0;
int trap_flag, singularity, solved;
token_type *ep, *source, *dest;
int n1, *nps, *np;
char *cp_start;
cp_start = cp;
if (current_not_defined()) {
return false;
}
n_tlhs = 0;
n_trhs = 0;
solved = solved_equation(cur_equation);
i = next_espace();
if (n_rhs[cur_equation]) {
if (!solved) {
warning(_("Not a solved equation."));
}
source = rhs[cur_equation];
nps = &n_rhs[cur_equation];
dest = rhs[i];
np = &n_rhs[i];
} else {
source = lhs[cur_equation];
nps = &n_lhs[cur_equation];
dest = lhs[i];
np = &n_lhs[i];
}
trap_flag = (strncasecmp(cp, "trap", 4) == 0);
if (trap_flag) {
cp = skip_param(cp);
}
if (*cp) {
cp = parse_var2(&v, cp);
if (cp == NULL) {
return false;
}
if (*cp) {
iterations = decstrtol(cp, &cp);
}
if (iterations <= 0 || (iterations % 2) != 0) {
error(_("Number of partitions must be a positive, even integer."));
return false;
}
}
if (*cp) {
input_column += (cp - cp_start);
cp = parse_expr(tlhs, &n_tlhs, cp, false);
if (cp == NULL || n_tlhs <= 0) {
return false;
}
}
if (*cp) {
cp_start = cp;
cp = skip_comma_space(cp);
input_column += (cp - cp_start);
cp = parse_expr(trhs, &n_trhs, cp, false);
if (cp == NULL || extra_characters(cp) || n_trhs <= 0) {
return false;
}
}
show_usage = false;
if (v == 0) {
if (!prompt_var(&v)) {
return false;
}
}
#if !SILENT
list_var(v, 0);
if (n_rhs[cur_equation]) {
fprintf(gfp, _("Numerically integrating the RHS with respect to %s...\n"), var_str);
} else {
fprintf(gfp, _("Numerically integrating with respect to %s...\n"), var_str);
}
#endif
singularity = false;
for (j = 1; j < *nps; j += 2) {
if (source[j].token.operatr == DIVIDE) {
for (k = j + 1; k < *nps && source[k].level >= source[j].level; k++) {
if (source[k].kind == VARIABLE && source[k].token.variable == v) {
singularity = true;
}
if (source[k].kind == OPERATOR && source[k].level == source[j].level)
break;
}
}
}
if (singularity) {
warning(_("Singularity detected, result of numerical integration might be wrong."));
}
if (n_tlhs == 0) {
my_strlcpy(prompt_str, _("Enter lower bound: "), sizeof(prompt_str));
if (!get_expr(tlhs, &n_tlhs)) {
return false;
}
}
subst_constants(tlhs, &n_tlhs);
simp_loop(tlhs, &n_tlhs);
if (exp_contains_infinity(tlhs, n_tlhs)) {
error(_("Not computable because: Lower bound contains infinity or NaN."));
return false;
}
if (n_trhs == 0) {
my_strlcpy(prompt_str, _("Enter upper bound: "), sizeof(prompt_str));
if (!get_expr(trhs, &n_trhs)) {
return false;
}
}
subst_constants(trhs, &n_trhs);
simp_loop(trhs, &n_trhs);
if (exp_contains_infinity(trhs, n_trhs)) {
error(_("Not computable because: Upper bound contains infinity or NaN."));
return false;
}
if ((n_tlhs + n_trhs + 3) > n_tokens) {
error_huge();
}
#if !SILENT
fprintf(gfp, _("Approximating the definite integral\n"));
if (trap_flag) {
fprintf(gfp, _("using the trapezoid method (%d partitions)...\n"), iterations);
} else {
fprintf(gfp, _("using Simpson's rule (%d partitions)...\n"), iterations);
}
#endif
subst_constants(source, nps);
simp_loop(source, nps);
for (j = 0; j < n_trhs; j++) {
trhs[j].level += 2;
}
trhs[n_trhs].level = 2;
trhs[n_trhs].kind = OPERATOR;
trhs[n_trhs].token.operatr = MINUS;
n_trhs++;
j = n_trhs;
blt(&trhs[n_trhs], tlhs, n_tlhs * sizeof(token_type));
n_trhs += n_tlhs;
for (; j < n_trhs; j++) {
trhs[j].level += 2;
}
trhs[n_trhs].level = 1;
trhs[n_trhs].kind = OPERATOR;
trhs[n_trhs].token.operatr = DIVIDE;
n_trhs++;
trhs[n_trhs].level = 1;
trhs[n_trhs].kind = CONSTANT;
trhs[n_trhs].token.constant = iterations;
n_trhs++;
simp_loop(trhs, &n_trhs);
dest[0] = zero_token;
n1 = 1;
for (j = 0; j <= iterations; j++) {
if ((n1 + 1 + *nps) > n_tokens)
error_huge();
for (k = 0; k < n1; k++) {
dest[k].level++;
}
ep = &dest[n1];
ep->level = 1;
ep->kind = OPERATOR;
ep->token.operatr = PLUS;
n1++;
i1 = n1;
blt(&dest[i1], source, *nps * sizeof(token_type));
n1 += *nps;
for (k = i1; k < n1; k++) {
dest[k].level += 2;
}
for (k = i1; k < n1; k += 2) {
if (dest[k].kind == VARIABLE && dest[k].token.variable == v) {
level = dest[k].level;
i2 = n_tlhs + 2 + n_trhs;
if ((n1 + i2) > n_tokens)
error_huge();
blt(&dest[k+1+i2], &dest[k+1], (n1 - (k + 1)) * sizeof(token_type));
n1 += i2;
i2 = k;
blt(&dest[k], tlhs, n_tlhs * sizeof(token_type));
k += n_tlhs;
level++;
for (; i2 < k; i2++) {
dest[i2].level += level;
}
ep = &dest[k];
ep->level = level;
ep->kind = OPERATOR;
ep->token.operatr = PLUS;
ep++;
level++;
ep->level = level;
ep->kind = CONSTANT;
ep->token.constant = j;
ep++;
ep->level = level;
ep->kind = OPERATOR;
ep->token.operatr = TIMES;
k += 3;
i2 = k;
blt(&dest[k], trhs, n_trhs * sizeof(token_type));
k += n_trhs;
for (; i2 < k; i2++) {
dest[i2].level += level;
}
k--;
}
}
if (j > 0 && j < iterations) {
if ((n1 + 2) > n_tokens)
error_huge();
ep = &dest[n1];
ep->level = 2;
ep->kind = OPERATOR;
ep->token.operatr = TIMES;
ep++;
ep->level = 2;
ep->kind = CONSTANT;
if (trap_flag) {
ep->token.constant = 2.0;
} else {
if ((j & 1) == 1) {
ep->token.constant = 4.0;
} else {
ep->token.constant = 2.0;
}
}
n1 += 2;
}
/* simplify and approximate the partial result quickly: */
approximate_roots = true;
elim_loop(dest, &n1);
ufactor(dest, &n1);
simp_divide(dest, &n1);
factor_imaginary(dest, &n1);
approximate_roots = false;
side_debug(1, dest, n1);
if (exp_contains_infinity(dest, n1)) {
error(_("Integration failed because result contains infinity or NaN (a singularity)."));
return false;
}
/* detect an ever growing result: */
switch (j) {
case 0:
break;
case 1:
first_size = n1;
if (first_size < 4)
first_size = 4;
break;
default:
if ((n1 / 8) >= first_size) {
error(_("Result growing, integration failed."));
return false;
}
break;
}
}
if ((n1 + 3 + n_trhs) > n_tokens)
error_huge();
for (k = 0; k < n1; k++)
dest[k].level++;
ep = &dest[n1];
ep->level = 1;
ep->kind = OPERATOR;
ep->token.operatr = DIVIDE;
ep++;
ep->level = 1;
ep->kind = CONSTANT;
if (trap_flag) {
ep->token.constant = 2.0;
} else {
ep->token.constant = 3.0;
}
ep++;
ep->level = 1;
ep->kind = OPERATOR;
ep->token.operatr = TIMES;
n1 += 3;
k = n1;
blt(&dest[k], trhs, n_trhs * sizeof(token_type));
n1 += n_trhs;
for (; k < n1; k++)
dest[k].level++;
/* simplify and approximate the result even more: */
approximate_roots = true;
do {
elim_loop(dest, &n1);
ufactor(dest, &n1);
simp_divide(dest, &n1);
} while (factor_imaginary(dest, &n1));
approximate_roots = false;
#if !SILENT
fprintf(gfp, _("Numerical integration successful:\n"));
#endif
*np = n1;
if (n_rhs[cur_equation]) {
blt(lhs[i], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type));
n_lhs[i] = n_lhs[cur_equation];
if (solved && isvarchar('\'')) {
len = list_var(lhs[i][0].token.variable, 0);
if (len > 0 && var_str[len-1] == '\'') {
var_str[--len] = '\0';
}
parse_var(&lhs[i][0].token.variable, var_str);
}
}
return return_result(i);
}

114
lib/README.txt Normal file
View File

@ -0,0 +1,114 @@
Mathomatic Symbolic Math Library
--------------------------------
This directory contains the API (Application Programming Interface) "lib.c"
and test/example programs "testmain.c" and "example.c" for the Mathomatic
symbolic math library. The API can be used to link your C compatible programs
with the Mathomatic symbolic math engine. This simple API provides for
passing C text strings containing expressions and commands to the Mathomatic
engine. If successful, a text string containing the resulting expression is
returned, otherwise an error message is returned.
Mathomatic is released under the GNU Lesser General Public License, so that
even closed-source software can make use of it.
This symbolic math library is at least able to be run anywhere the main
Mathomatic application can be run, and does not require an operating system
beyond the ability to allocate memory with malloc(3). The symbolic math
library is not re-entrant, meaning it cannot successfully be called again
until the last call to it completes. This is due to the fact that most data
storage areas in Mathomatic are global and static. I think that also means
Mathomatic is not threadsafe, correct me if I am wrong.
If you are trying to use this library as a plotting engine, please don't.
Every numerical calculation requires a memory move of half of the entire
expression for each and every number in it, to simplify a numerical
expression in Mathomatic. This will make 3D plots impossible and 2D plots
very slow. You need a library that parses to an expression tree and evaluates
that. Package "libmatheval1" will do this for you. It is available at
http://www.gnu.org/software/libmatheval/
and is free software that is currently maintained as of 2011.
To compile the Mathomatic symbolic math library and its test program, type
"make" while in this "lib" directory. This will create the static library
"libmathomatic.a" and the API test executable named "testmain". To run the
test executable, type "./testmain".
To do a system install of the development library "libmathomatic.a" and C
header file "mathomatic.h", type:
make flush
make
sudo make install
and enter your password. There are no tests, because the library uses the
same code as the Mathomatic application. If the application passes all tests,
the library should work too. "testmain" will successfully "read" in most of
the standard tests with the read command, until it encounters a calculate
command, which doesn't exist in the library, causing the read to terminate.
Just include the file "mathomatic.h" and call the functions in "lib.c" to use
this library. Link your program with "libmathomatic.a" by using "-lmathomatic
-lm" at the end of the ld linker command line. "libmathomatic.a" is not
required on the target system, since it is a static library, meaning it is
included in the resulting executable as needed.
The following code provides a quick test of this library:
char *output;
matho_init();
matho_parse("x^2=4", NULL);
matho_process("solve x", &output);
printf("%s\n", output);
Remember to free(output) on each successful call to matho_process() and
matho_parse() to return the memory used by the output string when you are
finished using it, otherwise there will be a memory leak. Here is the above
code fixed properly so it doesn't leak:
char *output;
int rv;
if (!matho_init()) {
printf("Not enough memory.\n");
exit(1);
}
matho_parse("x^2=4", NULL);
rv = matho_process("solve x", &output);
if (output) {
printf("%s\n", output);
if (rv) {
free(output);
} else {
printf("Error return.\n");
}
}
The above code is in the file "example.c" and the result of running the above
code when linked with the Mathomatic library should be:
x = 2*sign
The following Mathomatic commands are omitted in this library: calculate,
edit, plot, push, quit, and tally. To make up for the lack of the calculate
command, the replace, approximate, and "simplify sign" commands are provided,
allowing very similar functionality.
This paragraph is old information, you can now specify the integrate bounds
on the command-line. Recently, the "nintegrate" and "integrate definite"
commands are allowed; the bounds of integration are specified in the two
equation spaces following the current equation. cur_equation+1 is the lower
bound, and cur_equation+2 is the upper bound. Of course, the integrate and
nintegrate commands operate on the current equation, specified by the global
"cur_equation" variable (origin 0). The equation number displayed is always
origin 1, making it 1 greater than "cur_equation", so keep that in mind.
Please define the C preprocessor name HANDHELD=1 when compiling this library
for handheld computing devices like the iPhone and other small computing
devices, for reduced memory usage. For embedded devices with no file storage,
or for privacy or no wish to use file storage, define SECURE=1 too.
Please read the file "../README.txt" for more developer information. These
files were written by George Gesslein II of www.mathomatic.org

21
lib/compile.testmain Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh
# Shell script for creating the Mathomatic library test and example programs "testmain" and "example".
# testmain.c and example.c are compiled and linked with
# /usr/local/lib/libmathomatic.a or /usr/lib/libmathomatic.a
#
# If this fails, you probably need to compile and install the Mathomatic symbolic math library,
# by downloading the Mathomatic source code, then:
#
# cd lib
# make flush
# make lib
# sudo make install
CC=${CC-cc}
echo Compiling and linking testmain.c with currently installed libmathomatic.a
set -x
$CC -g -O3 -Wall -Wshadow -fexceptions $CFLAGS $CPPFLAGS $LDFLAGS testmain.c -lmathomatic -lm -o testmain && echo ./testmain created.
echo Compiling and linking example.c, too.
$CC -g -O3 -Wall -Wshadow -fexceptions $CFLAGS $CPPFLAGS $LDFLAGS example.c -lmathomatic -lm -o example && echo ./example created.
make clean # for any subsequent makes

41
lib/example.c Normal file
View File

@ -0,0 +1,41 @@
/*
* Real quick and dirty example of usage of the Mathomatic Symbolic Math Library.
* Designed to be as simple as possible, yet work.
* Just displays: "x = 2*sign".
*/
#include <stdio.h>
#include <stdlib.h>
#include "mathomatic.h"
int
main()
{
#if WANT_LEAKS /* Causes memory leaks, wrong code to use, but will work in a pinch. */
char *output;
matho_init();
matho_parse("x^2=4", NULL);
matho_process("solve x", &output);
printf("%s\n", output);
#else /* right code to use */
char *output;
int rv;
if (!matho_init()) {
printf("Not enough memory.\n");
exit(1);
}
matho_parse((char *) "x^2=4", NULL);
rv = matho_process((char *) "solve x", &output);
if (output) {
printf("%s\n", output);
if (rv) {
free(output);
} else {
printf("Error return.\n");
}
}
#endif
exit(0);
}

238
lib/lib.c Normal file
View File

@ -0,0 +1,238 @@
/*
* Mathomatic API, Copyright (C) 1996-2012 George Gesslein II.
*
* This file contains the required C functions and simple interface
* for developers to use the Mathomatic symbolic math library properly.
* These functions are included in the library.
* Refer to this, if you are going to use the Mathomatic code in other projects.
*
* Be sure to call matho_clear(3) to erase all equation spaces
* after completing each group of operations,
* otherwise the equation spaces will fill up.
*/
#include "../includes.h"
#include "mathomatic.h"
/** 3
* matho_init - Initialize the Mathomatic symbolic math library
* Call this only once before calling any Mathomatic code.
* This must be called exactly once upon program startup and not again,
* unless free_mem() is called.
*
* Returns true if successful.
* If this returns false, there was not enough memory available
* and Mathomatic cannot be used.
*/
int
matho_init(void)
{
init_gvars();
default_out = stdout; /* if default_out is a file that is not stdout, output is logged to that file */
gfp = default_out;
if (!init_mem()) {
return false;
}
signal(SIGFPE, fphandler); /* handle floating point exceptions, currently ignored */
return true;
}
/** 3
* matho_clear - Erase all equation spaces so they can be reused
* Mathomatic only has a limited number of equation spaces.
* Similar to a restart, recommended after each group of symbolic math operations.
* Currently this is the same as entering the command "clear all".
*
* matho_init(3) must have been called only one time before this
* to initialize the Mathomatic symbolic math engine.
*/
void
matho_clear(void)
{
clear_all();
}
/** 3
* matho_process - Process Mathomatic command or expression input
* Process a Mathomatic command or enter an expression into an equation space.
* The command or expression ASCII string is given as "input",
* the resulting output string is stored in "*outputp".
*
* matho_init(3) must have been called only one time before this
* to initialize the Mathomatic symbolic math engine.
* Use matho_clear(3) as many times as you want to restart Mathomatic
* for the next group of operations.
*
* This function works just like typing something into the Mathomatic prompt.
* To only parse any expression or equation and store it, use matho-parse(3).
*
* If this returns true (non-zero), the command or input was successful,
* and the resulting expression output string is stored in "*outputp".
* That is a malloc()ed text string which must be free()d after use
* to return the memory used by the string.
* The equation number of the equation space that the output expression
* is additionally stored in (if any) is available in the global "result_en",
* otherwise result_en = -1.
*
* If this returns false, the command or input failed and a text error
* message is always stored in "*outputp".
* The error message is a constant string and should NOT be free()d.
*
* Some commands, like the set command, will return no output when successful,
* setting "*outputp" to NULL.
*
* The resulting output string can safely be ignored by calling
* this function with "outputp" set to NULL.
*/
int
matho_process(char *input, char **outputp)
{
int i;
int rv;
if (outputp)
*outputp = NULL;
result_str = NULL;
result_en = -1;
error_str = NULL;
warning_str = NULL;
if (input == NULL)
return false;
input = strdup(input);
if ((i = setjmp(jmp_save)) != 0) {
clean_up(); /* Mathomatic processing was interrupted, so do a clean up. */
if (i == 14) {
error(_("Expression too large."));
}
if (outputp) {
if (error_str) {
*outputp = (char *) error_str;
} else {
*outputp = _("Processing was interrupted.");
}
}
free_result_str();
free(input);
previous_return_value = 0;
return false;
}
set_error_level(input);
rv = process(input);
if (rv) {
if (outputp) {
*outputp = result_str;
} else {
if (result_str) {
free(result_str);
result_str = NULL;
}
}
} else {
if (outputp) {
if (error_str) {
*outputp = (char *) error_str;
} else {
*outputp = _("Unknown error.");
}
}
free_result_str();
}
free(input);
return rv;
}
/** 3
* matho_parse - Process Mathomatic expression or equation input
* Parse a mathematical equation or expression and store in the next available equation space,
* making it the current equation.
* Afterwards, it can be operated on by Mathomatic commands using matho_process(3).
*
* matho_init(3) must have been called only one time before this
* to initialize the Mathomatic symbolic math engine.
* Use matho_clear(3) as many times as you want to restart Mathomatic
* for the next group of operations.
*
* The input and output ASCII strings are expressions, if successful.
* The expression or equation string to enter is in "input",
* the resulting output string is stored in "*outputp".
* The equation number of the equation space that the output expression
* is additionally stored in (if any) is available in the global "result_en",
* otherwise result_en = -1.
*
* Works the same as matho_process(3), except commands are not allowed,
* so that variables are not ever confused with commands.
* In fact, this function is currently set to only allow
* entry and storage of expressions and equations.
*
* Returns true (non-zero) if successful.
*/
int
matho_parse(char *input, char **outputp)
{
int i;
int rv;
if (outputp)
*outputp = NULL;
result_str = NULL;
result_en = -1;
error_str = NULL;
warning_str = NULL;
if (input == NULL)
return false;
input = strdup(input);
if ((i = setjmp(jmp_save)) != 0) {
clean_up(); /* Mathomatic processing was interrupted, so do a clean up. */
if (i == 14) {
error(_("Expression too large."));
}
if (outputp) {
if (error_str) {
*outputp = (char *) error_str;
} else {
*outputp = _("Processing was interrupted.");
}
}
free_result_str();
free(input);
return false;
}
set_error_level(input);
i = next_espace();
#if 1 /* Leave this as 1 if you want to be able to enter single variable or constant expressions with no solving or selecting. */
rv = parse(i, input); /* All set auto options ignored. */
#else
rv = process_parse(i, input); /* All set auto options respected. */
#endif
if (rv) {
if (outputp) {
*outputp = result_str;
} else {
if (result_str) {
free(result_str);
result_str = NULL;
}
}
} else {
if (outputp) {
if (error_str) {
*outputp = (char *) error_str;
} else {
*outputp = _("Unknown error.");
}
}
free_result_str();
}
free(input);
return rv;
}
/*
* Floating point exception handler.
* Usually doesn't work in most operating systems, so just ignore it.
*/
void
fphandler(int sig)
{
/* error(_("Floating point exception.")); */
}

92
lib/makefile Normal file
View File

@ -0,0 +1,92 @@
# Makefile for the Mathomatic symbolic math library and its test program.
# See file README.txt for instructions.
SHELL = /bin/sh # from http://www.gnu.org/prep/standards/
CC ?= gcc # C compiler to use
INSTALL ?= install # installer to use
INSTALL_PROGRAM ?= $(INSTALL) # command to install executable program files
INSTALL_DATA ?= $(INSTALL) -m 0644 # command to install data files
VERSION = `cat ../VERSION`
OPTFLAGS ?= -g -O3 -Wall -Wshadow -Wno-char-subscripts -Wno-unused-variable # gcc specific flags; can be removed
CFLAGS ?= $(OPTFLAGS)
CFLAGS += -fexceptions -DLIBRARY -DVERSION=\"$(VERSION)\" # necessary C compiler flags
LDLIBS += -lm # system libraries to link
# Install directories follow; installs everything in $(DESTDIR)/usr/local by default.
prefix ?= /usr/local
mandir ?= $(prefix)/share/man
libdir ?= $(prefix)/lib
includedir ?= $(prefix)/include
AOUT = testmain # The name of the library test executable file to create.
LIB = libmathomatic.a # The name of the symbolic math library file to create.
HEADERS = mathomatic.h
MATHOMATIC_OBJECTS += globals.o am.o solve.o help.o parse.o cmds.o simplify.o \
factor.o super.o unfactor.o poly.o diff.o integrate.o \
complex.o complex_lib.o list.o gcd.o factor_int.o
# man pages to automatically make and install:
MAN3 = matho_init.3 matho_clear.3 matho_parse.3 matho_process.3
.PHONY: all install uninstall clean distclean maintainer-clean flush lib manpages
all: lib $(AOUT)
lib: $(LIB) $(MAN3)
$(LIB): lib.o $(MATHOMATIC_OBJECTS)
$(AR) cr $(LIB) $+
-ranlib $(LIB)
@echo
@echo Symbolic math library $(LIB) created.
@echo
lib.o $(MATHOMATIC_OBJECTS): $(HEADERS) ../includes.h ../license.h ../standard.h ../am.h ../externs.h ../blt.h ../complex.h ../proto.h ../altproto.h ../VERSION
$(MATHOMATIC_OBJECTS): %.o: ../%.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
$(AOUT): testmain.o $(LIB)
$(CC) $(CFLAGS) $(LDFLAGS) $+ $(LDLIBS) -o $(AOUT)
@echo
@echo ./$(AOUT) created.
example: example.o $(LIB)
$(CC) $(CFLAGS) $(LDFLAGS) $+ $(LDLIBS) -o example
@echo
@echo ./example created.
# Generate the library man pages, if not already made.
# Requires the very latest version of txt2man.
manpages $(MAN3): lib.c
src2man -r "Mathomatic" -v "Symbolic Math Library" $+
install:
$(INSTALL) -d $(DESTDIR)$(libdir)
$(INSTALL) -d $(DESTDIR)$(includedir)
$(INSTALL) -d $(DESTDIR)$(mandir)/man3
$(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)
$(INSTALL_DATA) $(HEADERS) $(DESTDIR)$(includedir)
$(INSTALL_DATA) $(MAN3) $(DESTDIR)$(mandir)/man3
@echo
@echo Mathomatic Symbolic Math Library installed.
uninstall:
cd $(DESTDIR)$(mandir)/man3 && rm -f $(MAN3)
cd $(DESTDIR)$(includedir) && rm -f $(HEADERS)
rm -f $(DESTDIR)$(libdir)/$(LIB)
@echo
@echo Symbolic Math Library uninstall completed.
clean:
rm -f *.o
distclean flush: clean
rm -f $(AOUT) example
rm -f *.a
rm -f *.exe
maintainer-clean: distclean
rm -f $(MAN3)

22
lib/matho_clear.3 Normal file
View File

@ -0,0 +1,22 @@
.\" Extracted by src2man from lib.c
.\" Text automatically generated by txt2man
.TH matho_clear 3 "15 October 2012" "Mathomatic" "Symbolic Math Library"
.SH NAME
\fBmatho_clear \fP- Erase all equation spaces so they can be reused
.SH SYNOPSIS
.nf
.fam C
\fIvoid\fP \fBmatho_clear\fP(\fIvoid\fP);
.fam T
.fi
.fam T
.fi
.SH DESCRIPTION
Mathomatic only has a limited number of equation spaces.
Similar to a restart, recommended after each group of symbolic math operations.
Currently this is the same as entering the command "clear all".
.PP
\fBmatho_init\fP(3) must have been called only one time before this
to initialize the Mathomatic symbolic math engine.
.SH FILE
lib.c

23
lib/matho_init.3 Normal file
View File

@ -0,0 +1,23 @@
.\" Extracted by src2man from lib.c
.\" Text automatically generated by txt2man
.TH matho_init 3 "15 October 2012" "Mathomatic" "Symbolic Math Library"
.SH NAME
\fBmatho_init \fP- Initialize the Mathomatic symbolic math library
.SH SYNOPSIS
.nf
.fam C
int \fBmatho_init\fP(\fIvoid\fP);
.fam T
.fi
.fam T
.fi
.SH DESCRIPTION
Call this only once before calling any Mathomatic code.
This must be called exactly once upon program startup and not again,
unless \fBfree_mem\fP() is called.
.PP
Returns true if successful.
If this returns false, there was not enough memory available
and Mathomatic cannot be used.
.SH FILE
lib.c

38
lib/matho_parse.3 Normal file
View File

@ -0,0 +1,38 @@
.\" Extracted by src2man from lib.c
.\" Text automatically generated by txt2man
.TH matho_parse 3 "15 October 2012" "Mathomatic" "Symbolic Math Library"
.SH NAME
\fBmatho_parse \fP- Process Mathomatic expression or equation input
.SH SYNOPSIS
.nf
.fam C
int \fBmatho_parse\fP(char *\fIinput\fP, char **\fIoutputp\fP);
.fam T
.fi
.fam T
.fi
.SH DESCRIPTION
Parse a mathematical equation or expression and store in the next available equation space,
making it the current equation.
Afterwards, it can be operated on by Mathomatic commands using \fBmatho_process\fP(3).
.PP
\fBmatho_init\fP(3) must have been called only one time before this
to initialize the Mathomatic symbolic math engine.
Use \fBmatho_clear\fP(3) as many times as you want to restart Mathomatic
for the next group of operations.
.PP
The \fIinput\fP and output ASCII strings are expressions, if successful.
The expression or equation string to enter is in "\fIinput\fP",
the resulting output string is stored in "*\fIoutputp\fP".
The equation number of the equation space that the output expression
is additionally stored in (if any) is available in the global "result_en",
otherwise result_en = \fB-1\fP.
.PP
Works the same as \fBmatho_process\fP(3), except commands are not allowed,
so that variables are not ever confused with commands.
In fact, this function is currently set to only allow
entry and storage of expressions and equations.
.PP
Returns true (non-zero) if successful.
.SH FILE
lib.c

45
lib/matho_process.3 Normal file
View File

@ -0,0 +1,45 @@
.\" Extracted by src2man from lib.c
.\" Text automatically generated by txt2man
.TH matho_process 3 "15 October 2012" "Mathomatic" "Symbolic Math Library"
.SH NAME
\fBmatho_process \fP- Process Mathomatic command or expression input
.SH SYNOPSIS
.nf
.fam C
int \fBmatho_process\fP(char *\fIinput\fP, char **\fIoutputp\fP);
.fam T
.fi
.fam T
.fi
.SH DESCRIPTION
Process a Mathomatic command or enter an expression into an equation space.
The command or expression ASCII string is given as "\fIinput\fP",
the resulting output string is stored in "*\fIoutputp\fP".
.PP
\fBmatho_init\fP(3) must have been called only one time before this
to initialize the Mathomatic symbolic math engine.
Use \fBmatho_clear\fP(3) as many times as you want to restart Mathomatic
for the next group of operations.
.PP
This function works just like typing something into the Mathomatic prompt.
To only parse any expression or equation and store it, use \fBmatho-parse\fP(3).
.PP
If this returns true (non-zero), the command or \fIinput\fP was successful,
and the resulting expression output string is stored in "*\fIoutputp\fP".
That is a \fBmalloc\fP()ed text string which must be \fBfree\fP()d after use
to return the memory used by the string.
The equation number of the equation space that the output expression
is additionally stored in (if any) is available in the global "result_en",
otherwise result_en = \fB-1\fP.
.PP
If this returns false, the command or \fIinput\fP failed and a text error
message is always stored in "*\fIoutputp\fP".
The error message is a constant string and should NOT be \fBfree\fP()d.
.PP
Some commands, like the set command, will return no output when successful,
setting "*\fIoutputp\fP" to NULL.
.PP
The resulting output string can safely be ignored by calling
this function with "\fIoutputp\fP" set to NULL.
.SH FILE
lib.c

25
lib/mathomatic.h Normal file
View File

@ -0,0 +1,25 @@
/*
* Include file for user programs using the Mathomatic symbolic math library API.
*/
extern int matho_init(void); /* one-time Mathomatic initialization */
extern int matho_process(char *input, char **outputp); /* Mathomatic command or expression input */
extern int matho_parse(char *input, char **outputp); /* Mathomatic expression or equation input */
extern void matho_clear(void); /* Restart Mathomatic quickly and cleanly, replaces clear_all(). */
extern void free_mem(void); /* Free all allocated memory before quitting Mathomatic, if operating system doesn't when done. */
/* Mathomatic becomes unusable after free_mem(), until matho_init() is called again. */
/* Only Symbian OS is known to need a call to free_mem() before quitting. */
extern int load_rc(int return_true_if_no_file, FILE *ofp); /* Load Mathomatic startup set options from ~/.mathomaticrc, should allow "set save" to work. */
extern int cur_equation; /* current equation space number (origin 0) */
extern int result_en; /* Equation number of the API's returned result, */
/* if the result is also stored in an equation space, */
/* otherwise -1 for no equation number associated with result. */
/* Set by the last call to matho_parse() or matho_process(). */
/* Useful if you want to know where the result string is from, */
/* to act on it with further commands. */
extern const char *warning_str; /* optional warning message generated by the last command */

72
lib/testmain.c Normal file
View File

@ -0,0 +1,72 @@
/*
* This file contains the test/example program
* for the Mathomatic symbolic math library and API.
* Copy or refer to this,
* if you are going to use the Mathomatic code in your other projects.
*/
#include <stdio.h>
#include <stdlib.h>
#include "mathomatic.h"
int
main(int argc, char **argv)
{
char *cp; /* character pointer */
char *ocp; /* output character pointer */
int rv; /* return value */
char buf[10000]; /* input buffer */
char *version; /* version number of the library */
printf("Mathomatic library test/example program.\n");
/* Initialize all global variables and arrays so that Mathomatic will work properly. */
if (!matho_init()) { /* call this library function exactly once in your program */
fprintf(stderr, "Not enough memory.\n");
exit(1);
}
/* Mathomatic is ready for use. */
if (matho_process((char *) "version", &version)) {
printf("Mathomatic library version %s\n", version);
} else {
fprintf(stderr, "Error getting Symbolic Math Library version number.\n");
fprintf(stderr, "Mathomatic version command failed.\n");
exit(1);
}
/* Uncomment the following if you would like "set save" to save the current session settings for every future session. */
/* load_rc(true, NULL); */
/* This is a standard input/output loop for testing. */
printf("Press the EOF character (Control-D) to exit.\n");
for (;;) {
printf("%d-> ", cur_equation + 1);
fflush(stdout);
if ((cp = fgets(buf, sizeof(buf), stdin)) == NULL)
break;
/* Run the Mathomatic symbolic math engine. */
rv = matho_process(cp, &ocp);
if (warning_str) {
/* Optionally display any warnings (not required, but helpful). */
printf("Warning: %s\n", warning_str);
}
if (ocp) {
if (rv && result_en >= 0) {
/* Display the result equation number. */
printf("%d: ", result_en + 1);
}
/* Display the result. */
printf("Library result string:\n%s\n", ocp);
if (rv) {
free(ocp);
} else {
printf("Error return.\n");
}
}
}
#if VALGRIND
free(version);
free_mem(); /* reclaim all memory to check for memory leaks with something like valgrind(1) */
#endif
printf("\n");
exit(0);
}

50
license.h Normal file
View File

@ -0,0 +1,50 @@
/*
* This Mathomatic include file contains the current license notice.
*/
/* The following is the Mathomatic license notice, stored in a string. */
/* It is displayed by the "help copyright" command. */
char *license_string =
" Mathomatic computer algebra system\n"
" Copyright (C) 1987-2012 George Gesslein II\n\n"
"This library is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU Lesser General Public\n"
"License as published by the Free Software Foundation; either\n"
"version 2.1 of the License, or (at your option) any later version.\n\n"
"This library is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
"Lesser General Public License for more details.\n\n"
"You should have received a copy of the GNU Lesser General Public\n"
"License along with this library; if not, write to the Free Software\n"
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n"
"The full text of this license with details is contained in the file \"COPYING\"\n"
"in the Mathomatic source distribution, obtainable from \"www.mathomatic.org\";\n"
"All Mathomatic software and associated files (except for the documentation)\n"
"are published under this license. The Mathomatic documentation is licensed\n"
"under the GNU Free Documentation License (GFDL) version 1.3,\n"
"with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts,\n"
"so it can be easily published, corrected, and translated by anyone.\n\n"
"Chief author and copyright holder contact information:\n\n"
" email:\n"
" gesslein@mathomatic.org or\n"
" georgegesslein@gmail.com\n\n"
" postal address:\n"
" George Gesslein II\n"
" P.O. Box 224\n"
" Lansing, New York 14882-0224\n"
" USA\n\n"
"Most others who have kindly contributed working code or good ideas to\n"
"Mathomatic are listed in the files \"AUTHORS\" and \"changes.txt\".\n"
"Great merit is given to people that report bugs, in the file \"changes.txt\".\n"
"This means you will also show up in the file \"NEWS\".\n"
"To report a bug, simply email the author, or use the bug reporting facility\n"
"shown with \"help bugs\".\n";

1530
list.c Normal file

File diff suppressed because it is too large Load Diff

78
m4/README.txt Normal file
View File

@ -0,0 +1,78 @@
m4 Mathomatic
-------------
The executable named "mathomatic" is the best to run, however if you would
like functions, you need to run "rmath", which runs Mathomatic using GNU m4
as a macro pre-processor, allowing easy entry of standard math functions like
sqrt(x) and sin(x) (no logarithm function yet). "rmath" and "matho" are shell
scripts and are only known to work with GNU software. "rmath" runs "matho"
with a readline wrapper (rlwrap), if available. "matho" runs m4, reading
"functions.m4", and piping the output into Mathomatic. m4 Mathomatic will not
run under MS-Windows, unless m4 is provided by the third-party system CygWin.
To permanently install these program files along with their man pages on a
Unix-like system, if this is a binary distribution, type:
sudo ./matho-install
for trig functions with radian units. For trig with degree units, type:
sudo ./matho-install-degrees
These install commands may be repeated, the last one entered is current. This
binary distribution archive must be extracted to a directory and shell must
be running for the installation to work.
To undo the above commands and uninstall Mathomatic from your system, type:
sudo ./matho-uninstall
Installation is *not* necessary to run Mathomatic.
"sudo make m4install" or "sudo make m4install-degrees" is the proper way to
install these files from the source code distribution.
Defined m4 macros for functions and constants are listed in the file
"functions.m4" and the rmath man page. All trigonometric functions (sin(x),
tan(x), etc.) are implemented as complex exponentials in m4 Mathomatic, so
they can be simplified, manipulated, and calculated.
Mathomatic input is filtered by m4, so opening a shell or an editor doesn't
work when running m4 Mathomatic. These are disabled.
The "quit" and "exit" commands may have some delay. You can use the EOF
character (control-D) to quit instantly, instead.
The read command currently doesn't use m4, so it can't process functions. The
way to read in text files with functions is to supply the filenames on the
shell command line:
rmath filenames
All Mathomatic functions are real number, complex number, and symbolically
capable.
----------------------------------------------------------------------------
You can turn on color mode with the Mathomatic command:
set color
For brighter colors, use:
set bold color
typed at the Mathomatic main prompt. For dimmer colors, type:
set no bold
To turn off color mode, type:
set no color
You can save the current color state (and all other settings) with:
set save
so that Mathomatic starts up with your desired color setting every time.

15
m4/degrees.m4 Normal file
View File

@ -0,0 +1,15 @@
set no prompt
; Read this into rmath with "rmath degrees.m4" to use trig
; with arguments in degree units instead of radians.
; Standard trigonometry functions as complex exponentials follow.
; Argument x is in degrees.
m4_define(`sin', `((e**(i*(($1)*pi/180))-e**(-i*(($1)*pi/180)))/(2i))'); sin(x) = sine of x
m4_define(`cos', `((e**(i*(($1)*pi/180))+e**(-i*(($1)*pi/180)))/2)'); cos(x) = cosine of x
m4_define(`tan', `((e**(i*(($1)*pi/180))-e**(-i*(($1)*pi/180)))/(i*(e**(i*(($1)*pi/180))+e**(-i*(($1)*pi/180)))))'); tan(x) = tangent of x
m4_define(`cot', `(i*(e**(i*(($1)*pi/180))+e**(-i*(($1)*pi/180)))/(e**(i*(($1)*pi/180))-e**(-i*(($1)*pi/180))))'); cot(x) = cotangent of x
m4_define(`sec', `(2/(e**(i*(($1)*pi/180))+e**(-i*(($1)*pi/180))))'); sec(x) = secant of x
m4_define(`csc', `(2i/(e**(i*(($1)*pi/180))-e**(-i*(($1)*pi/180))))'); csc(x) = cosecant of x
echo Trig function arguments are now in degree units only.
set prompt >/dev/null

6
m4/file_id.diz Normal file
View File

@ -0,0 +1,6 @@
Mathomatic V16: Symbolic math program
This program can automatically solve,
simplify, compare, and calculate
algebraic equations, etc. Does
calculus operations, too. Free
to distribute.

49
m4/functions.m4 Normal file
View File

@ -0,0 +1,49 @@
set no prompt
; This m4 input file is used by the shell scripts "matho" and "rmath".
; This defines and enables named math functions in Mathomatic.
; Most functions here should be real number, complex number, and symbolically capable.
; m4 macro definitions for some elementary math functions and constants in Mathomatic.
m4_define(`sqrt', `(($1)**.5)'); function sqrt(x) = square root of x
m4_define(`cbrt', `(($1)**(1/3))'); function cbrt(x) = cube root of x
m4_define(`exp', `(e**($1))'); function exp(x) = e^x
m4_define(`pow', `(($1)**($2))'); function pow(x, y) = x^y
m4_define(`abs', `(|($1)|)'); function abs(x) = absolute value = |x|
m4_define(`sgn', `(($1)/|($1)|)'); signum function sgn(x) = sign of x; sgn(0) fails.
m4_define(`factorial', `(($1)!)'); factorial(x) function = x!
m4_define(`gamma', `((($1)-1)!)'); gamma(x) function = (x-1)!
m4_define(`phi', `((1+5**.5)/2)'); phi = the golden ratio constant, a root of x^2-x-1=0
m4_define(`omega', `(0.5671432904097838729999686622)'); an approximation of the Omega constant
m4_define(`euler', `(0.57721566490153286060651209008)'); the Euler-Mascheroni constant (approximation)
;set modulus_mode=2 >/dev/null ; mode 1 or 2 required for floor() and ceil().
m4_define(`floor', `(($1)-($1)%1)'); floor(x) = floor function, real x -> integer result
m4_define(`ceil', `(($1)+(-($1))%1)'); ceil(x) = ceiling function, real x -> integer result
m4_define(`int', `(($1)//1)'); int(x) = truncate to integer, real x -> integer result
m4_define(`round', `((($1)+|($1)|/($1)/2)//1)'); round(x) = round to nearest integer; beware, round(0) fails.
; Standard trigonometry functions as complex exponentials follow.
; Based on Euler's identity: e^(i*x) = cos(x) + i*sin(x)
; Argument x is in radians.
m4_define(`sin', `((e**(i*($1))-e**(-i*($1)))/(2i))'); sin(x) = sine of x
m4_define(`cos', `((e**(i*($1))+e**(-i*($1)))/2)'); cos(x) = cosine of x
m4_define(`tan', `((e**(i*($1))-e**(-i*($1)))/(i*(e**(i*($1))+e**(-i*($1)))))'); tan(x) = tangent of x
m4_define(`cot', `(i*(e**(i*($1))+e**(-i*($1)))/(e**(i*($1))-e**(-i*($1))))'); cot(x) = cotangent of x
m4_define(`sec', `(2/(e**(i*($1))+e**(-i*($1))))'); sec(x) = secant of x
m4_define(`csc', `(2i/(e**(i*($1))-e**(-i*($1))))'); csc(x) = cosecant of x
m4_define(`sinc', `(((e**(i*pi*($1))-e**(-i*pi*($1)))/(2i))/(pi*($1)))'); sinc(x) = normalized sinc function
; Standard hyperbolic trigonometry functions follow.
; Available are sinh(x), cosh(x), tanh(x), coth(x), sech(x), and csch(x).
; These are related to the above trigonometry functions without the "h" appended to the function name.
m4_define(`sinh', `((e**($1)-e**-($1))/2)')
m4_define(`cosh', `((e**($1)+e**-($1))/2)')
m4_define(`tanh', `((e**($1)-e**-($1))/(e**($1)+e**-($1)))')
m4_define(`coth', `((e**($1)+e**-($1))/(e**($1)-e**-($1)))')
m4_define(`sech', `(2/(e**($1)+e**-($1)))')
m4_define(`csch', `(2/(e**($1)-e**-($1)))')
echo Press the EOF character (Control-D) if you wish to exit Mathomatic.
echo Standard functions are now available, except for logarithms.
set prompt >/dev/null

15
m4/gradians.m4 Normal file
View File

@ -0,0 +1,15 @@
set no prompt
; Read this into rmath with "rmath gradians.m4" to use trig
; with arguments in gradian units instead of radians.
; Standard trigonometry functions as complex exponentials follow.
; Argument x is in gradians.
m4_define(`sin', `((e**(i*(($1)*pi/200))-e**(-i*(($1)*pi/200)))/(2i))'); sin(x) = sine of x
m4_define(`cos', `((e**(i*(($1)*pi/200))+e**(-i*(($1)*pi/200)))/2)'); cos(x) = cosine of x
m4_define(`tan', `((e**(i*(($1)*pi/200))-e**(-i*(($1)*pi/200)))/(i*(e**(i*(($1)*pi/200))+e**(-i*(($1)*pi/200)))))'); tan(x) = tangent of x
m4_define(`cot', `(i*(e**(i*(($1)*pi/200))+e**(-i*(($1)*pi/200)))/(e**(i*(($1)*pi/200))-e**(-i*(($1)*pi/200))))'); cot(x) = cotangent of x
m4_define(`sec', `(2/(e**(i*(($1)*pi/200))+e**(-i*(($1)*pi/200))))'); sec(x) = secant of x
m4_define(`csc', `(2i/(e**(i*(($1)*pi/200))-e**(-i*(($1)*pi/200))))'); csc(x) = cosecant of x
echo Trig function arguments are now in gradian units only.
set prompt >/dev/null

32
m4/matho Executable file
View File

@ -0,0 +1,32 @@
#!/bin/sh
# This shell script runs Mathomatic with the GNU m4 macro pre-processor so that
# standard math functions such as sqrt(x), sin(x), etc. may be easily entered.
# Hyperbolic trig has "h" appended, like sinh(x) for hyperbolic sine.
# Only works with GNU software.
# See file "functions.m4" for the complete list of supported functions,
# or type "man rmath" at the shell prompt.
#
# Usage: matho [ input_files ]
MATHOMATIC="${0}matic"
MFUNCTIONS="${0%/matho}/functions.m4"
MOPTIONS="-ru -s-1"
if ! m4 --version >/dev/null
then
echo The \"m4\" package is not installed. GNU m4 is required to run m4 Mathomatic.
exit 1
fi
if [ -x "$MATHOMATIC" ]
then
echo Running "$MATHOMATIC"
m4 -eP -- "$MFUNCTIONS" "$@" - | "$MATHOMATIC" $MOPTIONS
elif [ -x ../mathomatic ]
then
echo Running ../mathomatic
m4 -eP -- "$MFUNCTIONS" "$@" - | ../mathomatic $MOPTIONS
else
echo Running mathomatic
m4 -eP -- "$MFUNCTIONS" "$@" - | mathomatic $MOPTIONS
fi

31
m4/matho-install Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh
# This shell script installs m4 Mathomatic so that any user can use it.
# If this is a source distribution, you should change directory to its root,
# and compile Mathomatic and "sudo make m4install" to install everything.
# If this is a binary distribution, you should type "sudo ./matho-install"
# from this directory to install the program files and man pages.
PREFIX=/usr/local
BINDIR=$PREFIX/bin
MANDIR=$PREFIX/share/man/man1
MAN1="mathomatic.1 rmath.1"
MATHOMATIC=mathomatic
if [ ! -x "$MATHOMATIC" ]
then
MATHOMATIC="../$MATHOMATIC"
fi
if [ ! -x "$MATHOMATIC" ]
then
echo mathomatic executable not found.
exit
fi
echo Installing "$MATHOMATIC" to "$BINDIR"
set -x
mkdir -p $BINDIR
mkdir -p $MANDIR
cp $MAN1 $MANDIR
ln -sf $MANDIR/rmath.1 $MANDIR/matho.1
cp "$MATHOMATIC" functions.m4 matho rmath "$BINDIR" && echo Done! && exit
echo
echo Usage: sudo $0

32
m4/matho-install-degrees Executable file
View File

@ -0,0 +1,32 @@
#!/bin/sh
# This shell script installs m4 Mathomatic with trig functions that use degree units.
# If this is a source distribution, you should change directory to its root,
# and compile Mathomatic and "sudo make m4install-degrees" to install everything.
# If this is a binary distribution, you should type "sudo ./matho-install-degrees"
# from this directory to install the program files and man pages.
PREFIX=/usr/local
BINDIR=$PREFIX/bin
MANDIR=$PREFIX/share/man/man1
MAN1="mathomatic.1 rmath.1"
MATHOMATIC=mathomatic
if [ ! -x "$MATHOMATIC" ]
then
MATHOMATIC="../$MATHOMATIC"
fi
if [ ! -x "$MATHOMATIC" ]
then
echo mathomatic executable not found.
exit
fi
echo Installing "$MATHOMATIC" to "$BINDIR"
set -x
mkdir -p $BINDIR
mkdir -p $MANDIR
cp $MAN1 $MANDIR
ln -sf $MANDIR/rmath.1 $MANDIR/matho.1
cp "$MATHOMATIC" functions.m4 matho rmath "$BINDIR" &&
cat degrees.m4 >>"$BINDIR"/functions.m4 && echo Done! && exit
echo
echo Usage: sudo $0

24
m4/matho-uninstall Executable file
View File

@ -0,0 +1,24 @@
#!/bin/sh
# This shell script uninstalls m4 Mathomatic if installed
# with matho-install or matho-install-degrees.
# To uninstall Mathomatic from your computer,
# type "sudo ./matho-uninstall".
PREFIX=/usr/local
BINDIR=$PREFIX/bin
MANDIR=$PREFIX/share/man/man1
MATHOMATIC=mathomatic
BINFILES="$MATHOMATIC matho rmath functions.m4"
MANFILES="mathomatic.1 rmath.1 matho.1"
set -x
for file in $BINFILES;
do
rm -f "$BINDIR"/"$file";
done
for file in $MANFILES;
do
rm -f "$MANDIR"/"$file";
done
echo "$MATHOMATIC" uninstalled.

21
m4/rmath Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh
# This shell script runs m4 Mathomatic (matho) with readline capability.
# Uses rlwrap program, if available, which is a readline front end.
# The rlwrap program may be obtained at
# http://utopia.knoware.nl/~hlub/uck/rlwrap/
#
# Usage: rmath [ input_files ]
MATHOPATH="${0%/rmath}/matho"
if [ ! -x "$MATHOPATH" ]
then
MATHOPATH=matho
fi
if rlwrap true
then
rlwrap -H ~/.matho_history "$MATHOPATH" "$@"
else
echo readline support not loaded because \"rlwrap\" utility was not found.
"$MATHOPATH" "$@"
fi

561
main.c Normal file
View File

@ -0,0 +1,561 @@
/*
* This file contains main() and the startup code for Mathomatic,
* which is a computer algebra system written in the C programming language.
*
* Copyright (C) 1987-2012 George Gesslein II.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The chief copyright holder can be contacted at gesslein@mathomatic.org, or
George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA.
*/
/*
* Output to stderr is only done in this file. The rest of the Mathomatic code
* should not output to stderr; error messages should use error() or go to stdout.
* One reason for this is so that Mathomatic stdout can be redirected or piped,
* catching all output.
*
* This program only supports binary and unary operators.
* Unary operators are implemented as a binary operation with a dummy operand.
*
* In the storage format, each level of parentheses is indicated
* by a level number (origin 1). The deeper the level, the
* higher the level number.
*
* The storage format for expressions is a fixed size array of elements
* "token_type", which may be a CONSTANT, VARIABLE, or OPERATOR.
* The array always alternates between operand (CONSTANT or VARIABLE)
* and OPERATOR. There is a separate integer for each array which
* contains the current length of the expression stored in the array.
* This length is always odd and must never exceed "n_tokens".
*
* In the storage format,
* any number of TIMES and DIVIDE operators may be on the same level of parentheses,
* because they are similar and the most basic multiplicative class operators.
* The same for the PLUS and MINUS operators, because they are similar (additive class).
* All other operators are only allowed one single operator per level of parentheses,
* and no same nor different operators may be with it on that level within the current grouping.
*
* Most of the expression manipulation and comparison routines are recursive,
* calling themselves for each level of parentheses.
*
* Note that equation space numbers internally are 1 less than the equation
* space numbers displayed. That is because internal equation space numbers
* are origin 0 array indexes, while displayed equation numbers are origin 1.
*
* See the file "am.h" to start understanding the Mathomatic code and
* to adjust memory usage.
*
* C types "long long" and "long double" are not used at all in Mathomatic,
* because many architectures and compilers do not support them. These large C
* types can be used in the Mathomatic Prime Number Tools though, producing
* larger prime numbers and quickly on a 64-bit computer. 64 bits is the size
* of a double, so Mathomatic runs optimally on a 64-bit system.
*/
#if !LIBRARY /* This comments out this whole file if compiling as the symbolic math library. */
#include "includes.h"
#if !NO_GETOPT_H
#include <getopt.h>
#endif
#if WIN32_CONSOLE_COLORS
#include <windows.h>
#include <wincon.h>
HANDLE hOut;
#endif
/*
* Display invocation usage info.
*/
void
usage(fp)
FILE *fp;
{
fprintf(fp, _("Mathomatic computer algebra system, version %s\n"), VERSION);
fprintf(fp, _("Usage: %s [ options ] [ input_files or input ]\n\n"), prog_name);
fprintf(fp, _("Options:\n"));
fprintf(fp, _(" -a Enable alternative color mode.\n"));
fprintf(fp, _(" -b Enable bold color mode.\n"));
fprintf(fp, _(" -c Toggle color mode.\n"));
fprintf(fp, _(" -d Set demo mode (no pausing).\n"));
fprintf(fp, _(" -e Process expressions and commands on the command line.\n"));
fprintf(fp, _(" -h Display this help and exit.\n"));
fprintf(fp, _(" -m number Specify a memory size multiplier.\n"));
fprintf(fp, _(" -q Set quiet mode (don't display prompts).\n"));
fprintf(fp, _(" -r Disable readline or editline.\n"));
fprintf(fp, _(" -s level:time Set enforced security level and max time for user's session.\n"));
fprintf(fp, _(" -t Set test mode. Use when comparing program output.\n"));
fprintf(fp, _(" -u Set unbuffered output with input echo.\n"));
fprintf(fp, _(" -v Display version number, then exit successfully.\n"));
fprintf(fp, _(" -w Wide output mode, sets unlimited width.\n"));
fprintf(fp, _(" -x Enable HTML/XHTML output mode.\n"));
fprintf(fp, _("\nPlease refer to the man page for details (type \"man mathomatic\" in shell).\n"));
}
int
main(argc, argv)
int argc;
char **argv;
{
#if NO_GETOPT_H /* if no getopt.h is available */
extern char *optarg; /* set by getopt(3) */
extern int optind;
#endif
int i, rv;
char *cp = NULL;
double numerator, denominator;
double new_size = 0;
int aoption = false, coption = false, boption = false, wide_flag = false;
int exit_value = 0;
unsigned int time_out_seconds = 0;
#if WIN32_CONSOLE_COLORS
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
#endif
#if I18N
/* Initialize internationalization so that messages are in the right language. */
setlocale(LC_ALL, "");
bindtextdomain(prog_name, LOCALEDIR);
textdomain(prog_name);
#endif
#if CYGWIN || MINGW
dir_path = strdup(dirname_win(argv[0])); /* set dir_path to this executable's directory */
#endif
/* initialize the global variables */
init_gvars();
default_out = stdout; /* set default_out to any file you want to redirect output to */
gfp = default_out;
get_screen_size();
/* process command line options */
while ((i = getopt(argc, argv, "s:abqrtdchuvwxm:e")) >= 0) {
switch (i) {
case 's':
if (optarg) {
security_level = strtod(optarg, &cp);
#if SECURE
if (security_level != 4) {
fprintf(stderr, _("%s: Already compiled for maximum security (level 4), therefore setting security level ignored.\n"), prog_name);
}
#endif
}
if (optarg == NULL || cp == NULL || (cp == optarg && *cp != ':') || (*cp != '\0' && *cp != ':')) {
fprintf(stderr, _("%s: Error in setting security level.\n"), prog_name);
exit(2);
}
if (*cp == ':') {
time_out_seconds = strtol(cp + 1, &cp, 10);
if (!(*cp == '\0' && time_out_seconds > 0)) {
fprintf(stderr, _("%s: Error in setting time out seconds.\n"), prog_name);
exit(2);
}
}
#if !SECURE
if (time_out_seconds > 0) {
printf(_("Security level is %d, time out seconds is %d.\n"), security_level, time_out_seconds);
}
#endif
break;
case 'w':
wide_flag = true;
break;
case 'a':
aoption = true;
break;
case 'b':
boption = true;
break;
case 'c':
coption++;
break;
case 'x':
html_flag = 1;
wide_flag = true;
break;
case 'm':
if (optarg)
new_size = strtod(optarg, &cp) * DEFAULT_N_TOKENS;
if (optarg == NULL || cp == NULL || *cp || new_size <= 0 || new_size >= (INT_MAX / sizeof(token_type))) {
fprintf(stderr, _("%s: Invalid memory size multiplier specified.\n"), prog_name);
exit(2);
}
n_tokens = (int) new_size;
break;
case 'q':
quiet_mode = true;
break;
case 'r':
readline_enabled = false;
break;
case 't':
readline_enabled = false;
wide_flag = true;
test_mode = true;
break;
case 'd':
demo_mode = true;
break;
case 'u':
echo_input = true;
setbuf(stdout, NULL); /* make output unbuffered */
setbuf(stderr, NULL);
break;
case 'h':
usage(stdout);
exit(0);
case 'v':
/* Don't be fancy, this may be used to test for existence. */
printf(_("Mathomatic version %s\n"), VERSION);
exit(0);
case 'e':
eoption = true;
autoselect = false;
break;
default:
usage(stdout);
exit(2);
}
}
if (n_tokens < 100 || n_tokens >= (INT_MAX / sizeof(token_type))) {
fprintf(stderr, _("%s: Standard expression array size %d out of range!\n"), prog_name, n_tokens);
}
if (!init_mem()) {
fprintf(stderr, _("%s: Not enough memory.\n"), prog_name);
exit(2);
}
#if READLINE
if (readline_enabled) { /* readline_enabled flag must not change after this */
if ((cp = getenv("HOME"))) {
#if MINGW
snprintf(history_filename_storage, sizeof(history_filename_storage), "%s/matho_history", cp);
#else
snprintf(history_filename_storage, sizeof(history_filename_storage), "%s/.matho_history", cp);
#endif
history_filename = history_filename_storage;
}
using_history(); /* initialize readline history */
rl_initialize(); /* initialize readline */
stifle_history(500); /* maximum of 500 entries */
rl_inhibit_completion = true; /* turn off readline file name completion */
#if 0 /* not 100% tested and this might confuse the user with the -c toggle */
#if !WIN32_CONSOLE_COLORS
if (!html_flag) { /* If doing ANSI color: */
color_flag = (tigetnum("colors") >= 8); /* autoset color output mode. Requires ncurses. */
}
#endif
#endif
#if !SECURE
if (security_level <= 3) {
read_history(history_filename); /* restore readline history of previous session */
}
#endif
}
#endif
if (html_flag) {
printf("<pre>\n");
}
if (!test_mode && !quiet_mode && !eoption) {
display_startup_message(stdout);
}
fflush(stdout);
#if !SECURE
/* read the user options initialization file */
if (security_level <= 3 && !test_mode && !demo_mode && !load_rc(true, NULL)) {
fprintf(stderr, _("%s: Error loading startup set options from \"%s\".\n"), prog_name, rc_file);
fprintf(stderr, _("Use the \"set no save\" command to startup with the program defaults every time.\n\n"));
}
#endif
if (wide_flag) {
screen_columns = 0;
screen_rows = 0;
}
if (coption & 1) {
color_flag = !color_flag;
}
if (boption) {
color_flag = 1;
bold_colors = 1;
}
if (color_flag && aoption) {
color_flag = 2;
}
if (test_mode) {
color_flag = 0;
} else if (!quiet_mode && !eoption) {
if (color_flag) {
#if WIN32_CONSOLE_COLORS
if (color_flag == 2) {
printf(_("%s%s color mode enabled"), html_flag ? "HTML" : "ANSI", bold_colors ? " bold" : "");
} else {
printf(_("%s%s color mode enabled"), html_flag ? "HTML" : "WIN32 CONSOLE", bold_colors ? " bold" : "");
}
#else
printf(_("%s%s color mode enabled"), html_flag ? "HTML" : "ANSI", bold_colors ? " bold" : "");
#endif
printf(_("; manage by typing \"help color\".\n"));
} else {
printf(_("Color mode turned off; manage it by typing \"help color\".\n"));
}
}
fflush(stdout);
if ((i = setjmp(jmp_save)) != 0) {
/* for error handling */
clean_up();
switch (i) {
case 14:
error(_("Expression too large."));
default:
printf(_("Operation aborted.\n"));
break;
}
previous_return_value = 0;
if (eoption)
exit_value = 1;
} else {
if ((rv = set_signals(time_out_seconds))) {
fprintf(stderr, _("C signal handler setting failed!\n"));
#if DEBUG
fprintf(stderr, "Failing signal is \"%s\".\n", strsignal(rv));
#endif
exit_value = 2;
}
if (!f_to_fraction(0.5, &numerator, &denominator)
|| numerator != 1.0 || denominator != 2.0
|| !f_to_fraction(1.0/3.0, &numerator, &denominator)
|| numerator != 1.0 || denominator != 3.0) {
fprintf(stderr, _("%s: Cannot convert any floating point values to fractions!\n"), prog_name);
fprintf(stderr, _("Roots will not work properly.\n"));
exit_value = 2;
}
if (max_memory_usage() <= 0) {
fprintf(stderr, _("%s: Calculated maximum memory usage overflows a long integer!\n"), prog_name);
exit_value = 2;
}
if (eoption) {
/* process expressions and commands from the command line */
for (i = optind; i < argc && argv[i]; i++) {
if (!display_process(argv[i])) {
exit_value = 1;
}
}
} else {
#if SECURE
if (!quiet_mode && !test_mode)
printf(_("Anything done here is temporary.\n"));
if (optind < argc) {
warning(_("File arguments ignored in high security mode."));
}
#else
if (!quiet_mode && !test_mode) {
if (optind < argc) {
printf(_("Reading in file%s specified on the command line...\n"), (optind == (argc - 1)) ? "" : "s");
} else {
if (security_level >= 2) {
printf(_("Anything done here is temporary.\n"));
} else {
printf(_("Anything done here is temporary, unless it is saved or redirected.\n"));
}
}
}
/* read in files specified on the command line, exit if error */
for (i = optind; i < argc && argv[i]; i++) {
if (strcmp(argv[i], "-") == 0) {
main_io_loop();
} else if (!read_file(argv[i])) {
fflush(NULL); /* flush all output */
fprintf(stderr, _("Read of file \"%s\" failed.\n"), argv[i]);
exit_program(1);
}
}
#endif
}
}
if (!eoption)
main_io_loop(); /* main input/output loop */
exit_program(exit_value); /* exit Mathomatic, doesn't return */
return(exit_value); /* so the compiler doesn't complain */
}
/*
* Repeatedly read a line of text from standard input and process the expression or command.
*/
void
main_io_loop(void)
{
char *cp = NULL;
for (;;) {
error_str = NULL;
warning_str = NULL;
default_color(false);
snprintf(prompt_str, sizeof(prompt_str), "%d%s", cur_equation + 1, html_flag ? HTML_PROMPT_STR : PROMPT_STR);
if ((cp = get_string((char *) tlhs, n_tokens * sizeof(token_type))) == NULL)
break;
process(cp);
}
}
/*
* All signal(2) initialization goes here.
* Attach all necessary C signals to their handler functions.
*
* Return zero on success, or a non-zero unsettable signal number on error.
*/
int
set_signals(time_out_seconds)
unsigned int time_out_seconds;
{
int rv = 0;
if (signal(SIGFPE, fphandler) == SIG_ERR)
rv = SIGFPE;
if (signal(SIGINT, inthandler) == SIG_ERR)
rv = SIGINT;
if (signal(SIGTERM, exithandler) == SIG_ERR)
rv = SIGTERM;
#if 0 /* Crashes entire shell window when readline is used and SIGHUP received. */
if (signal(SIGHUP, exithandler) == SIG_ERR)
rv = SIGHUP;
#endif
#if UNIX || CYGWIN
if (signal(SIGWINCH, resizehandler) == SIG_ERR)
rv = SIGWINCH;
#endif
#if 0 /* Crashes entire shell when readline is used. */
if (signal(SIGALRM, alarmhandler) == SIG_ERR)
rv = SIGALRM;
#endif
#if !MINGW
if (time_out_seconds > 0) {
alarm(time_out_seconds);
#if TIMEOUT_SECONDS
} else {
alarm(TIMEOUT_SECONDS);
#endif
}
#endif
return rv;
}
/*
* Floating point exception handler.
* Floating point exceptions are currently ignored.
*/
void
fphandler(sig)
int sig;
{
#if DEBUG
warning("Floating point exception.");
#endif
}
/*
* Fancy Control-C (interrupt) signal handler.
* Interrupts processing and returns to main prompt through a polling mechanism.
* If it can't, repeated calls terminate this program.
*/
void
inthandler(sig)
int sig;
{
abort_flag++;
switch (abort_flag) {
case 0:
case 1:
/* wait for graceful abort */
printf(_("\nUser interrupt signal received; three times in a row quits Mathomatic.\n"));
return;
case 2:
printf(_("\nPress Control-C once more to quit program.\n"));
return;
default:
/* abruptly quit this program */
printf(_("\nRepeatedly interrupted; returning to operating system...\n"));
exit_program(1);
}
}
#if 0
/*
* Alarm signal handler.
*/
void
alarmhandler(sig)
int sig;
{
printf(_("\nTimeout, quitting...\n"));
exit_program(1);
}
#endif
/*
* Signal handler for proper exiting to the operating system.
*/
void
exithandler(sig)
int sig;
{
exit_program(1);
}
#if UNIX || CYGWIN
/*
* Window resize signal handler.
*/
void
resizehandler(sig)
int sig;
{
if (screen_columns)
get_screen_size();
}
#endif
/*
* Properly exit this program and return to the operating system.
*/
void
exit_program(exit_value)
int exit_value; /* zero if OK, non-zero indicates error return */
{
reset_attr();
if (html_flag) {
printf("</pre>\n");
}
#if READLINE && !SECURE
if (readline_enabled && security_level <= 3) {
write_history(history_filename); /* save readline history */
}
#endif
if (exit_value == 0 && !quiet_mode && !eoption && !html_flag) {
printf(_("ByeBye!! from Mathomatic.\n"));
}
#if VALGRIND
printf("Deallocating all Mathomatic allocated memory for valgrind memory leak checking...\n");
printf("If you are not using valgrind, please compile without -DVALGRIND.\n");
free_mem(); /* Free all known memory buffers to check for memory leaks with something like valgrind(1). */
#endif
exit(exit_value);
}
#endif

344
makefile Normal file
View File

@ -0,0 +1,344 @@
# Makefile for compiling, testing, and installing Mathomatic and its documentation.
# Requires the GNU make utility, in BSD Unix this is called "gmake".
# Remove the -DUNIX define in CFLAGS when not using Mathomatic for desktop UNIX/Linux.
# For normal compilation and testing on a GNU system,
# please type the following at the shell prompt:
# make clean
# make READLINE=1
# make test
#
# For Slackware, or any other OS that fails to find the curses library functions, use:
# LDLIBS=-lncurses make READLINE=1
# for the second make line.
#
# To use the Tiny C Compiler (tcc) to compile Mathomatic:
# make clean
# CC=tcc LDFLAGS="-L/usr/lib/x86_64-linux-gnu/ -L/lib/x86_64-linux-gnu/" make READLINE=1
# make test
# The -L options might need to be set to the library directories your current gcc uses,
# as the above example shows.
# They will probably differ from the above, try "locate libm." to find your library paths,
# one or two of them will probably work.
# To install the base Mathomatic system after compiling and testing, type:
# make install
# if that doesn't work, try:
# sudo make install
# and enter your password. This is because write permission is required to /usr/local/*.
#
# To install all of Mathomatic, including m4 Mathomatic (rmath), instead type:
# make m4install
# or:
# sudo make m4install
# To compile, test, and install all of Mathomatic under CygWin for MS-Windows:
# CFLAGS="-DCYGWIN -DBOLD_COLOR -O3" make READLINE=1
# make test
# make m4install
# To compile Mathomatic with the MinGW cross-compiler for MS-Windows under Debian or Ubuntu:
# sudo apt-get install gcc-mingw32
# ./compile.mingw
# This will create Windows executables for Mathomatic and the Prime Number Tools.
# For cross-compiling under other systems, just edit "compile.mingw".
# To compile, test, and install all of Mathomatic under OpenIndiana (SunOS), type:
# LDLIBS=-lcurses make READLINE=1
# make test
# sudo make m4install INSTALL=ginstall prefix=/usr M4=gm4
# This makefile does NOT compile and install the Prime Number Tools in the "primes" directory,
# nor does it compile and install the Symbolic Math Library in the "lib" directory.
# sudo make uninstall
# here will uninstall all of Mathomatic,
# including the Prime Number Tools and the Symbolic Math Library,
# but it must know the "prefix" used to install Mathomatic, if specified during the install.
SHELL = /bin/sh # from "http://www.gnu.org/prep/standards/", do not change
CC ?= gcc # C compiler to use; this statement doesn't work usually, instead using cc.
M4 ?= m4 # Change this to gm4 in Unix or a non-GNU system.
INSTALL ?= install # Installer utility to use; change to ginstall under Unix.
INSTALL_PROGRAM ?= $(INSTALL) # Command to install executable program files.
INSTALL_DATA ?= $(INSTALL) -m 0644 # Command to install data files.
CC_OPTIMIZE ?= -O3 # Default C compiler optimization flags that are safe (but please remove for LLVM/Clang, see "misc/known_bugs.txt").
# Be sure and run tests to see if Mathomatic works and runs faster, if you uncomment the following line:
#CC_OPTIMIZE += -fno-signaling-nans -fno-trapping-math -fomit-frame-pointer # Possible additional optimizations, not tested.
VERSION = `cat VERSION`
OPTFLAGS ?= $(CC_OPTIMIZE) -Wall -Wshadow -Wno-char-subscripts # optional gcc specific flags
CFLAGS ?= $(OPTFLAGS)
CFLAGS += -fexceptions -DUNIX -DVERSION=\"$(VERSION)\"
LDLIBS += -lm # libraries to link with to create the Mathomatic executable
# Run "make READLINE=1" to include the optional readline editing and history support:
CFLAGS += $(READLINE:1=-DREADLINE)
LDLIBS += $(READLINE:1=-lreadline) # Add -lncurses if needed for readline, might be called "curses" on some systems.
# Run "make EDITLINE=1" to include the optional editline editing and history support (smaller than readline):
CFLAGS += $(EDITLINE:1=-DEDITLINE)
LDLIBS += $(EDITLINE:1=-leditline)
# Uncomment the following line to force generation of x86-64-bit code:
#CFLAGS += -m64
# Install directories follow; installs everything in $(DESTDIR)/usr/local by default.
# Note that support for the DESTDIR variable was added in version 15.2.1.
# DESTDIR is used by package maintainers, who should remove all DESTDIR patches,
# because DESTDIR is handled properly (according to GNU standards) by this makefile now.
prefix ?= /usr/local
bindir ?= $(prefix)/bin
datadir ?= $(prefix)/share
mandir ?= $(prefix)/share/man
docdir ?= $(prefix)/share/doc
mathdocdir ?= $(docdir)/mathomatic
mathdatadir ?= $(datadir)/mathomatic
# Mathomatic program names:
AOUT ?= mathomatic
M4SCRIPTPATH = $(DESTDIR)$(bindir)/matho
INCLUDES = includes.h license.h standard.h am.h externs.h blt.h complex.h proto.h altproto.h
MATHOMATIC_OBJECTS += main.o globals.o am.o solve.o help.o parse.o cmds.o simplify.o \
factor.o super.o unfactor.o poly.o diff.o integrate.o \
complex.o complex_lib.o list.o gcd.o factor_int.o
PRIMES_MANHTML = doc/matho-primes.1.html doc/matho-pascal.1.html doc/matho-sumsq.1.html \
doc/primorial.1.html doc/matho-mult.1.html doc/matho-sum.1.html
# HTML man pages to make:
MANHTML = doc/mathomatic.1.html doc/rmath.1.html $(PRIMES_MANHTML)
# Flags to make HTML man pages with rman:
RMANOPTS = -f HTML -r '%s.%s.html'
RMAN = rman
# Flags to make HTML man pages with groff instead (uncomment below and comment above to use):
#RMANOPTS = -man -Thtml -P -l
#RMAN = groff
# man pages to install:
MAN1 = mathomatic.1 rmath.1
# Text files to install:
TEXT_DOCS ?= VERSION AUTHORS COPYING README.txt NEWS
PDFDOC = manual.pdf # Name of PDF file containing the Mathomatic User Guide and Command Reference.
PDFMAN = bookman.pdf # Name of PDF file containing all the Mathomatic man pages.
all static: $(AOUT) html NEWS # make these by default
# Make sure the HTML man pages are up-to-date.
html: $(MANHTML)
# Make the Quick Reference Card.
htmlcard doc/quickrefcard.html: $(AOUT)
./makehtmlcard.sh doc/ # shell script that uses awk to make a nice command reference card
# Make the PDF cheat sheet.
pdfsheet quickref.pdf: $(AOUT)
./makepdfsheet.sh doc/ # shell script
# TEST MATHOMATIC
# Run "make test" to see if the resulting mathomatic executable runs properly on your system.
# It does a diff between the output of the test and the expected output.
# If no differences are reported, "All tests passed 100% correctly" is displayed.
test:
@echo
@echo Testing ./$(AOUT) \(`./$(AOUT) -v`\)
cd tests && time -p ../$(AOUT) -t all 0<&- >test.out && diff -u --strip-trailing-cr all.out test.out && rm test.out && cd ..
@echo "All tests passed 100% correctly."
# Same as "make test", except it doesn't run the time command.
check:
@echo
@echo Testing ./$(AOUT) \(`./$(AOUT) -v`\)
cd tests && ../$(AOUT) -t all 0<&- >test.out && diff -u --strip-trailing-cr all.out test.out && rm test.out && cd ..
@echo "All tests passed 100% correctly."
# "make baseline" generates the expected output file for "make test".
# Do not run this unless you are sure Mathomatic is working correctly
# and you need "make test" to succeed with no errors.
baseline tests/all.out:
cd tests && ../$(AOUT) -t all 0<&- >all.out && cd ..
@rm -f tests/test.out
@echo
@echo File tests/all.out updated with current test output.
# BUILD MATHOMATIC
# ./update updates the function prototypes in proto.h by using the cproto utility.
# Run ./update whenever a new C function is added to the Mathomatic source code or
# whenever a function definition is changed.
proto.h:
./update # shell script
$(MATHOMATIC_OBJECTS): $(INCLUDES) VERSION
# To compile Mathomatic as a stand-alone executable
# that has no shared library dependencies, type "make clean static".
static: LDFLAGS += -static
# Create the mathomatic executable:
$(AOUT): $(MATHOMATIC_OBJECTS)
$(CC) $(CFLAGS) $(LDFLAGS) $+ $(LDLIBS) -o $(AOUT)
@echo
@echo ./$(AOUT) successfully created.
# BUILD THE MATHOMATIC DOCUMENTATION
# Build the nicely ordered changelog.
NEWS: changes.txt makenews.sh
./makenews.sh # shell script
# "make pdfdoc" creates the PDF version of the Mathomatic User Guide and Command Reference, if desired.
# Requires the htmldoc program be installed.
pdf pdfdoc $(PDFDOC): doc/manual.html doc/am.html doc/fdl-1.3-standalone.html
htmldoc --webpage --format pdf --title --logoimage icons/mathomatic.png --footer h1l --header "c d" -f $(PDFDOC) $+
@echo Mathomatic PDF user documentation $(PDFDOC) generated.
# "make pdfman" creates a PDF of all the Mathomatic Man pages, if desired.
# Requires the very latest version of the txt2man package.
bookman pdfman $(PDFMAN): $(MAN1) primes/*.1 lib/*.3
bookman -p -t "Mathomatic version $(VERSION) Man Pages" -a "George Gesslein II" -d `date +%F` $+ >$(PDFMAN) </dev/null
@echo Complete Mathomatic PDF man pages book created in $(PDFMAN)
# Here we convert the man pages to HTML docs with rman:
doc/mathomatic.1.html: mathomatic.1
$(RMAN) $(RMANOPTS) $< >/dev/null # Test for the success of rman command.
@tidy -version >/dev/null
-$(RMAN) $(RMANOPTS) $< | tidy -q -i -file /dev/null >$@
@echo Successfully created $@
doc/rmath.1.html: rmath.1
$(RMAN) $(RMANOPTS) $< >/dev/null # Test for the success of rman command.
@tidy -version >/dev/null
-$(RMAN) $(RMANOPTS) $< | tidy -q -i -file /dev/null >$@
@echo Successfully created $@
$(PRIMES_MANHTML): doc/%.1.html: primes/%.1
$(RMAN) $(RMANOPTS) $< >/dev/null # Test for the success of rman command.
@tidy -version >/dev/null
-$(RMAN) $(RMANOPTS) $< | tidy -q -i -file /dev/null >$@
@echo Successfully created $@
# INSTALL MATHOMATIC
# The following installs everything, including m4 Mathomatic with documentation.
m4install: install matho-rmath-install
@echo
@echo m4 Mathomatic install completed.
@echo
# The following installs shell scripts matho and rmath,
# allowing convenient entry of standard math functions.
# Requires at least "make bininstall" first.
matho-rmath-install:
$(INSTALL) -d $(DESTDIR)$(mathdatadir)
$(INSTALL) -d $(DESTDIR)$(mathdatadir)/m4
echo '#!/bin/sh' >$(M4SCRIPTPATH)
echo '# Shell script to run Mathomatic with the GNU m4 preprocessor.' >>$(M4SCRIPTPATH)
echo '# This allows entry of many standard math functions.' >>$(M4SCRIPTPATH)
echo '#' >>$(M4SCRIPTPATH)
echo '# Usage: matho [ input_files ]' >>$(M4SCRIPTPATH)
echo >>$(M4SCRIPTPATH)
echo 'if ! $(M4) --version >/dev/null' >>$(M4SCRIPTPATH)
echo 'then' >>$(M4SCRIPTPATH)
echo ' echo The $(M4) package is not installed. GNU m4 is required to run m4 Mathomatic.' >>$(M4SCRIPTPATH)
echo ' exit 1' >>$(M4SCRIPTPATH)
echo 'fi' >>$(M4SCRIPTPATH)
echo >>$(M4SCRIPTPATH)
echo '$(M4) -eP -- $(mathdatadir)/m4/functions.m4 "$$@" - | mathomatic -ru -s-1' >>$(M4SCRIPTPATH)
chmod 0755 $(M4SCRIPTPATH)
$(INSTALL_PROGRAM) m4/rmath $(DESTDIR)$(bindir)
$(INSTALL_DATA) rmath.1 $(DESTDIR)$(mandir)/man1
cd $(DESTDIR)$(mandir)/man1 && ln -sf rmath.1 matho.1
$(INSTALL_DATA) m4/functions.m4 m4/degrees.m4 m4/gradians.m4 $(DESTDIR)$(mathdatadir)/m4
# Install m4 Mathomatic with trig functions that use degree units, instead of radians.
matho-rmath-install-degrees: matho-rmath-install
cat m4/degrees.m4 >>$(DESTDIR)$(mathdatadir)/m4/functions.m4
@echo Degree mode installed.
# Install complete m4 Mathomatic with trig functions that use degree units, instead of radians.
m4install-degrees: m4install
cat m4/degrees.m4 >>$(DESTDIR)$(mathdatadir)/m4/functions.m4
@echo Degree mode installed.
# Install the Mathomatic binaries and documentation. Does not install m4 Mathomatic.
install: bininstall docinstall
@echo
@echo Mathomatic is installed.
@echo
# Strip the binaries of their symbol tables. Makes smaller executables, but debugging becomes impossible.
strip: $(AOUT)
strip $(AOUT)
# Binaries only install.
bininstall:
$(INSTALL) -d $(DESTDIR)$(bindir)
$(INSTALL) -d $(DESTDIR)$(datadir)/applications
$(INSTALL) -d $(DESTDIR)$(datadir)/pixmaps
$(INSTALL) -d $(DESTDIR)$(mandir)/man1
$(INSTALL_PROGRAM) $(AOUT) $(DESTDIR)$(bindir)
$(INSTALL_DATA) icons/mathomatic.desktop $(DESTDIR)$(datadir)/applications
$(INSTALL_DATA) icons/mathomatic.png icons/mathomatic.xpm $(DESTDIR)$(datadir)/pixmaps
$(INSTALL_DATA) mathomatic.1 $(DESTDIR)$(mandir)/man1
# Documentation only install.
docinstall:
@echo Installing docs...
$(INSTALL) -d $(DESTDIR)$(mathdocdir)
$(INSTALL) -d $(DESTDIR)$(mathdocdir)/html
$(INSTALL) -d $(DESTDIR)$(mathdocdir)/tests
$(INSTALL) -d $(DESTDIR)$(mathdocdir)/examples
$(INSTALL_DATA) $(TEXT_DOCS) $(DESTDIR)$(mathdocdir)
$(INSTALL_DATA) doc/* $(DESTDIR)$(mathdocdir)/html
-$(INSTALL_DATA) *.pdf $(DESTDIR)$(mathdocdir)
$(INSTALL_DATA) tests/* $(DESTDIR)$(mathdocdir)/tests
$(INSTALL_DATA) examples/* $(DESTDIR)$(mathdocdir)/examples
# UNINSTALL MATHOMATIC
# Entirely remove Mathomatic from your local computer system.
uninstall:
cd $(DESTDIR)$(mandir)/man1 && rm -f $(MAN1) matho.1
cd $(DESTDIR)$(bindir) && rm -f $(AOUT) rmath matho
rm -rf $(DESTDIR)$(mathdocdir)
rm -rf $(DESTDIR)$(mathdatadir)
rm -f $(DESTDIR)$(datadir)/applications/mathomatic.desktop
rm -f $(DESTDIR)$(datadir)/pixmaps/mathomatic.*
@echo
@echo Mathomatic uninstall completed.
@echo
-$(MAKE) -C primes prefix=$(prefix) uninstall
@echo
-$(MAKE) -C lib prefix=$(prefix) uninstall
# CLEAN THIS DIRECTORY
# Tidy this directory and sub-directories after building, testing, and installing Mathomatic.
# Useful to run before a build make, to be sure we are building something complete and new.
clean:
rm -f *.o *.pyc *.pyo
rm -f */*.o */*.pyc */*.pyo
rm -f tests/test.out primes/test.out primes/bigtest.out
# distclean cleans everything to the defaults, before distributing the source code
# from this directory, if it has not been corrupted or carelessly modified.
distclean: clean
rm -f *.a */*.a
rm -f $(AOUT)
rm -f mathomatic_secure
rm -f *.exe
rm -f *.pdf
$(MAKE) -C primes distclean
$(MAKE) -C lib distclean
# maintainer-clean prepares to rebuild absolutely everything. Not recommended.
maintainer-clean flush: distclean
rm -f $(MANHTML)
./update # shell script to update proto.h using the cproto utility.
# make a clean distribution out of this directory in ~/am.zip
zip: distclean
./zipsrc # shell script

54
makehtmlcard.awk Normal file
View File

@ -0,0 +1,54 @@
# Convert TAB delimited Mathomatic help file to HTML.
# See "makehtmlcard.sh".
# Usage awk -F"\t" -f makehtmlcard.awk infile.txt >outfile.html
# Credit goes to John Blommers (http://www.blommers.org) for starting this awk file and for the cheat sheet idea.
BEGIN {
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 TRANSITIONAL//EN\">"
print "<html>"
print "<head>"
}
NR==1 {
print "<title>Mathomatic Quick Reference Card</title>"
print "</head>"
print "<body>"
print "<table cellpadding=\"4\" border=\"3\" summary=\"Mathomatic Quick Reference Card\">"
print "<tr bgcolor=\"#2648fe\">" "<th colspan=\"3\">" "<font color=\"white\">" $1 "</font>" "</th>" "</tr>"
}
NR==2 {
print "<tr>"
print "<th>" $1 "</th>"
print "<th>" $2 "</th>"
print "<th>" $3 "</th>"
print "</tr>"
}
NR>2 {
print "<tr>"
print "<td nowrap=\"nowrap\">" $1 "</td>"
print "<td nowrap=\"nowrap\">" $2 "</td>"
print "<td nowrap=\"nowrap\">" $3 "</td>"
print "</tr>"
}
END {
print "</table>"
print "<br clear=all>"
# print "<p>"
print "<font size=\"+1\">"
print "Anything enclosed by straight brackets <b>[like this]</b> means it is optional and may be omitted."
print "</font>"
# print "<p>"
# print "<font size=\"+1\">"
# print "To select an equation space and make it the current equation, type the equation number at the main prompt.<br>"
# print "To solve the current equation, type the variable name at the main prompt or use the solve command."
# print "</font>"
print "<p>"
print "<font size=\"+1\">"
print "<strong>For more information, visit <a href=\"http://www.mathomatic.org\">www.mathomatic.org</a></strong>"
print "</font>"
print "</body>"
print "</html>"
}

14
makehtmlcard.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh
set -e
textfile="$1"quickrefcard.txt
trap "echo Removing \"$textfile\"; rm -f \"$textfile\"" EXIT
echo Creating Mathomatic Quick Reference Card named: "$1"quickrefcard.html
./mathomatic -e "help table >$textfile"
echo Running awk...
awk -F"\t" -f makehtmlcard.awk "$textfile" >"$1"quickrefcard.html
echo Created "$1"quickrefcard.html
echo Use print to PDF file in Firefox to create the PDF quick reference card.
# pisa "$1"quickrefcard.html "$1"quickrefcard.pdf

14
makenews.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh
# Make forward order changelog in "NEWS" file from changes.txt:
set -e
(echo; echo "The latest version of Mathomatic is `cat VERSION`, here are the changes:"; tac -r -s "^Mathomatic version.*$" changes.txt) | head -n -9 >NEWS.tmp
echo >>NEWS.tmp
echo ---------------------------------------------------------------------- >>NEWS.tmp
echo End of this version history of the Mathomatic computer algebra system. >>NEWS.tmp
echo Current as of `date '+%D'` \(`date '+%F'`\). >>NEWS.tmp
echo The latest changes are at the beginning of this file. >>NEWS.tmp
echo This file is always available up-to-date at http://mathomatic.org/NEWS >>NEWS.tmp
echo Alternatively, you can get it at http://mathomatic.orgserve.de/NEWS >>NEWS.tmp
echo Do not edit this file, edit the end of changes.txt instead. >>NEWS.tmp
echo Written and maintained by George Gesslein II. >>NEWS.tmp
mv NEWS.tmp NEWS

33
makepdfsheet.sh Executable file
View File

@ -0,0 +1,33 @@
#!/bin/sh
htmlfile="$1"quickref.html
pdffile=quickref.pdf
echo Generating the Mathomatic Quick Reference Sheet PDF file...
echo "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 TRANSITIONAL//EN\">" >"$htmlfile"
echo '<html>' >>"$htmlfile"
echo '<head>' >>"$htmlfile"
echo '<title>Mathomatic Quick Reference Sheet</title>' >>"$htmlfile"
echo '</head>' >>"$htmlfile"
echo '<body>' >>"$htmlfile"
echo '<pre>' >>"$htmlfile"
./mathomatic -e "set html all" "help all main equations constants >>$htmlfile" || (rm "$htmlfile"; exit 1)
echo >>"$htmlfile"
echo '<strong>For more information, visit <a href="http://www.mathomatic.org">www.mathomatic.org</a></strong>' >>"$htmlfile"
echo '</pre>' >>"$htmlfile"
echo '</body>' >>"$htmlfile"
echo '</html>' >>"$htmlfile"
if htmldoc --webpage --format pdf --linkstyle plain --no-links -f "$pdffile" "$htmlfile"
then
echo "$pdffile" successfully created.
rm "$htmlfile"
exit 0
else
rm "$htmlfile"
exit 1
fi

221
mathomatic.1 Normal file
View File

@ -0,0 +1,221 @@
.TH MATHOMATIC 1
.SH NAME
mathomatic \- a computer algebra system
.SH SYNOPSIS
.B mathomatic
[
.B \-abcdehqrtuvwx
] [
.B \-s
level:time
] [
.B \-m
number
] [
input_files or input
]
.SH DESCRIPTION
Mathomatic is a general-purpose computer algebra system (CAS)
that can symbolically solve, simplify, combine, and compare algebraic equations,
perform standard, complex number, modular, and polynomial arithmetic, etc.
It does some calculus and handles all elementary algebra, except logarithms.
Trigonometry and function expansion are supported in a separate program called
.BR rmath (1).
Plotting expressions with
.B gnuplot
is also supported.
.B mathomatic
is the main Mathomatic application that does interactive symbolic-numeric mathematics
through a simple command-line interface.
Readline or editline support is usually compiled into this application,
making it easy to edit input and recall previous input with the cursor keys.
The numeric arithmetic is double precision floating point
with about 14 decimal digits accuracy.
Many results will be exact,
because symbolic math is an exact math, and
because multiple floating point numbers
can be combined for a single mathematical value; for example:
.B 2^(1/3),
which is the cube root of 2 exactly.
.SH OPTIONS
.TP
.B \-a
Enable alternative colors.
Ansi color mode will be enabled in MS-Windows, if this option is specified and color mode is on.
.TP
.B \-b
Enable bold colors.
Color mode will be turned on and colors will be brighter if this option is specified.
Same as the "set bold color" command.
.TP
.B \-c
Toggle color mode.
This mode outputs ANSI terminal escape sequences to make each level of
parentheses a different color, for easier reading.
Requires a terminal emulator that supports ANSI color escape sequences.
If the colors are too hard to see, use the
.B \-b
option to increase the color brightness.
.TP
.B \-d
Set demo mode.
Currently this mode only bypasses loading the startup (rc) file, and ignores the pause command.
It also allows using the calculate command without prompting for the values of any of the variables.
.TP
.B \-e
Process mathematical expressions and Mathomatic commands
instead of input files on the shell command line, and then quit.
Unquoted space characters are the line separators
on the Mathomatic input that follows this option.
Works similar to entering it into the Mathomatic main prompt,
except the autoselect option is turned off.
Useful for quick command-line calculations.
The startup messages are not displayed with this option.
Follow this option with "\-\-" so that
expressions can start with a minus sign (\-).
.TP
.B \-h
Display a brief help message listing all of these options and then exit.
.TP
.B \-m number
Change the memory size of equation spaces.
It is followed by a decimal, floating point number which is a multiplier
of the default equation space size.
This allows larger equation spaces so that manipulating extremely
large expressions will succeed without getting the
"Expression too large" error.
Specifying a number higher than 100 may make Mathomatic unresponsive.
.TP
.B \-q
Set quiet mode.
The startup messages and prompts are not displayed.
This is useful when piping or redirecting input into Mathomatic,
because the input won't be displayed,
so prompt output should be turned off.
This option does the same thing as the "set no prompt" command.
.TP
.B \-r
Disable readline or editline input processing.
Readline, and the editline drop-in replacement library,
allow line input editing using the cursor keys,
and output terminal control codes,
all of which can be turned off with this option.
.TP
.B \-s level:time
Set the enforced security level for the user's Mathomatic session.
Level 0 is the default with no security.
Level 1 disallows shelling out (forking).
Level 2 disallows shelling out and writing files.
Level 3 disallows shelling out and reading/writing files.
Level 4 is the highest security level and is the same as compiling with the \-DSECURE option.
This run-time option was created for use on open public servers.
Specifying a colon, then a time in seconds, will time limit the application for that session.
.TP
.B \-t
Set test mode.
Used when testing and comparing output.
Bypasses loading startup (rc) file, turns off color mode and readline,
sets wide output mode, ignores the pause command, etc.
It also allows using the calculate command without prompting for the values of any of the variables.
.TP
.B \-u
Guarantee that standard output and standard error output are unbuffered.
Also echoes all line input if not in quiet mode (
.B \-q
option ).
Useful when piping.
.TP
.B \-v
Display program name and version number, then exit successfully.
.TP
.B \-w
Set wide output mode for an unlimited width output device
like the "set wide" command does.
Sets infinite screen columns and rows so that 2D (two-dimensional)
expression output will always succeed
and not be downgraded to 1D output when it doesn't fit in the display area.
Use when redirecting output or with a terminal emulator that doesn't wrap lines.
This mode only affects 2D output.
.TP
.B \-x
Enable HTML output mode (which is also valid XHTML).
This makes Mathomatic output suitable for inclusion in a web page.
Color and bold mode affect this mode, allowing HTML color output.
Wide output mode is also set by this option, meaning expressions
will always be displayed in 2D.
.SH GENERAL
After any options, text files may be specified on the shell command line
that will be automatically read in with the read command, unless the
.B \-e
option is specified.
Mathomatic is best run from within a terminal emulator.
It uses console line input and output for the user interface.
First you type in your mathematical equations in standard algebraic notation,
then you can solve them by typing in the variable name at the prompt, or
perform operations on them with simple English commands.
Type "help" or "?" for the help command, "help examples" to get started.
If the command name is longer than 4 letters, you only need
to type in the first 4 letters.
Most commands operate on the current equation by default.
A command preceded by an exclamation point (such as "!ls") is taken to
be a shell command and is passed unchanged to the shell (/bin/sh).
"!" by itself invokes the default shell, which is specified in the SHELL environment variable.
"!" is also the factorial operator.
Complete documentation is available in HTML and PDF formats;
see the local documentation directory or online at "http://mathomatic.org/math/doc/"
for the latest Mathomatic documentation.
.SH ENVIRONMENT
.TP
.B EDITOR
The EDITOR environment variable specifies which text editor to use for the edit command.
.SH FILES
.TP
.B ~/.mathomaticrc
Optional startup file containing Mathomatic set command options.
It should be a text file with one or more set options per line.
For example, the line "no color" will make Mathomatic default to non-color mode,
which is useful if you aren't using a supported color device.
.SH AUTHOR
Mathomatic has been written by George Gesslein II (gesslein@mathomatic.org),
with help from the Internet community.
.SH "REPORTING BUGS"
The command to take the limit of an expression is partially functional and experimental.
All else should work perfectly; if not,
please report it as a bug to the author or
on the Launchpad website: "https://launchpad.net/mathomatic".
.SH "SEE ALSO"
.BR rmath (1),
.BR matho-primes (1),
.BR primorial (1),
.BR matho-mult (1),
.BR matho-sum (1),
.BR matho-pascal (1),
.BR matho-sumsq (1)

7
menu/README.txt Normal file
View File

@ -0,0 +1,7 @@
The Debian Menu System provides a unified menu interface for both text and
X Windows oriented programs, without having to configure each window manager.
These are the Debian Menu System files for Mathomatic.
"mathomatic" and "mathomatic-primes" go in "/usr/share/menu".
They should be put there by the Debian mathomatic package.

7
menu/mathomatic Normal file
View File

@ -0,0 +1,7 @@
?package(mathomatic):\
needs="text"\
hints="Mathomatic"\
section="Applications/Science/Mathematics"\
title="Mathomatic"\
command="/usr/bin/mathomatic"\
icon="/usr/share/pixmaps/mathomatic.xpm"

Some files were not shown because too many files have changed in this diff Show More