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.
29
AUTHORS
Normal 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
@ -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
@ -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
@ -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
@ -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
@ -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
|
||||
31
altproto.h
Normal 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);
|
||||
201
am.h
Normal 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 "−> " /* 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
@ -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
@ -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
54
compile.mingw
Executable 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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
59
doc/doc.css
Normal 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
|
After Width: | Height: | Size: 318 B |
488
doc/fdl-1.3-standalone.html
Normal 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 © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
|
||||
<<a href="http://fsf.org/">http://fsf.org/</a>>
|
||||
</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 "free" 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 "copyleft", 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 "Document", below,
|
||||
refers to any such manual or work. Any member of the public is a
|
||||
licensee, and is addressed as "you". You accept the license if you
|
||||
copy, modify or distribute the work in a way requiring permission
|
||||
under copyright law.</p>
|
||||
|
||||
<p>A "Modified Version" 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 "Secondary Section" 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 "Invariant Sections" 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 "Cover Texts" 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 "Transparent" 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 "Transparent" is called "Opaque".</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 "Title Page" 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, "Title Page" 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 "publisher" means any person or entity that distributes copies of
|
||||
the Document to the public.</p>
|
||||
|
||||
<p>A section "Entitled XYZ" 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 "Acknowledgements",
|
||||
"Dedications", "Endorsements", or "History".) To "Preserve the Title"
|
||||
of such a section when you modify the Document means that it remains a
|
||||
section "Entitled XYZ" 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 "History", 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 "History" 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 "History" 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 "Acknowledgements" or "Dedications",
|
||||
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 "Endorsements". Such a section
|
||||
may not be included in the Modified Version.
|
||||
</li>
|
||||
|
||||
<li>N. Do not retitle any existing section to be Entitled "Endorsements"
|
||||
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 "Endorsements", provided it contains
|
||||
nothing but endorsements of your Modified Version by various
|
||||
parties—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 "History"
|
||||
in the various original documents, forming one section Entitled
|
||||
"History"; likewise combine any sections Entitled "Acknowledgements",
|
||||
and any sections Entitled "Dedications". You must delete all sections
|
||||
Entitled "Endorsements".</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 "aggregate" 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 "Acknowledgements",
|
||||
"Dedications", or "History", 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 "or any later version" 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>"Massive Multiauthor Collaboration Site" (or "MMC Site") 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
|
||||
"Massive Multiauthor Collaboration" (or "MMC") contained in the site
|
||||
means any set of copyrightable works thus published on the MMC site.</p>
|
||||
|
||||
<p>"CC-BY-SA" 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>"Incorporate" means to publish or republish a Document, in whole or in
|
||||
part, as part of another Document.</p>
|
||||
|
||||
<p>An MMC is "eligible for relicensing" 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 "GNU
|
||||
Free Documentation License".
|
||||
</pre>
|
||||
|
||||
<p>If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
|
||||
replace the "with … Texts." 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
|
After Width: | Height: | Size: 1.7 KiB |
BIN
doc/greenfade.png
Normal file
|
After Width: | Height: | Size: 893 B |
87
doc/index.html
Normal 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="© 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 © 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
|
After Width: | Height: | Size: 1.1 KiB |
795
doc/manual.html
Normal 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="© 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 (∑) and product (∏),
|
||||
|
||||
<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—> " 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—> a=b-(c+2)
|
||||
|
||||
#1: a = b − c − 2
|
||||
|
||||
1—> b
|
||||
|
||||
#1: b = 2 + c + a
|
||||
|
||||
1—> calculate
|
||||
Enter a: 1
|
||||
Enter c: 1
|
||||
|
||||
b = 4
|
||||
|
||||
1—>
|
||||
</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—> 3*(x-1) + 1 = 2x + 1
|
||||
|
||||
#1: (3·(x − 1)) + 1 = (2·x) + 1
|
||||
|
||||
1—> simplify
|
||||
|
||||
#1: (3·x) − 2 = (2·x) + 1
|
||||
|
||||
1—> solve verify x
|
||||
|
||||
#1: x = 3
|
||||
|
||||
Solution verified.
|
||||
1—>
|
||||
</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>±1.797693e+308</b> (slightly less than 2^1024).
|
||||
<li>
|
||||
The smallest valid constant is <b>±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 ±infinity which would be more correct.
|
||||
Also, floating point overflow produces either positive or negative infinity.
|
||||
|
||||
<pre class="sample">
|
||||
1—> 1/0
|
||||
Warning: Division by zero.
|
||||
|
||||
answer = inf
|
||||
|
||||
1—> 0/0
|
||||
Warning: Division by zero.
|
||||
|
||||
answer = nan
|
||||
|
||||
1—>
|
||||
</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>ê</b>, or <b>e#</b> - the universal constant e (2.718281828…)<br>
|
||||
<b>pi</b> or <b>pi#</b> - the universal constant pi (3.1415926…)<br>
|
||||
<b>i</b>, <b>î</b>, or <b>i#</b> - the imaginary unit (square root of -1)<br>
|
||||
<b>sign</b>, <b>sign1</b>, <b>sign2</b>, … - may only be +1 or -1<br>
|
||||
<b>integer</b>, <b>integer1</b>, … - 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 "+/−".
|
||||
|
||||
<a name="operators"></a>
|
||||
<h3>Operators</h3>
|
||||
<p>
|
||||
Mathomatic implements the standard rules of algebra for
|
||||
addition (<b>+</b>), subtraction (<b>−</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>−</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 © 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
@ -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
@ -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’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’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’s triangle is the sum of the
|
||||
two numbers immediately above it.</p>
|
||||
|
||||
<p>Each line of Pascal’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’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
@ -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
@ -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
@ -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
@ -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’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’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’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.</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’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
|
After Width: | Height: | Size: 189 B |
BIN
doc/open_book_nae_02.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
68
doc/primorial.1.html
Normal 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
@ -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
@ -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’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’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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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;
|
||||
568
factor_int.c
Normal 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
@ -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, "ient1);
|
||||
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
@ -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;
|
||||
13
icons/README.txt
Normal 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
@ -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
@ -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
BIN
icons/mathomatic.ico
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
icons/mathomatic.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
130
icons/mathomatic.svg
Normal 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
@ -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
|
After Width: | Height: | Size: 232 B |
119
includes.h
Normal 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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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";
|
||||
78
m4/README.txt
Normal 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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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"
|
||||