?function ?? |
Function names should be given without quotes. Note that function names are case-sensitive in Yacas but the ? facility will also respond to all lowercase names.
The directive ?? displays the index to all documentation.
Documentation is displayed in a Web browser of your choice. The default choice is lynx. An alternative browser can be set using the SetHelpBrowser function.
In> ?Random |
In> ?makefunctionplugin |
Get help on a keyword:
In> ?arity |
Browse all documentation:
In> ?? |
quit restart |
The directives quit and restart are not reserved words or variable names. They take effect only when typed as first characters at a prompt.
Pressing Ctrl-C will stop the currently running calculation. If there is no currently running calculation, Ctrl-C will quit the interpreter.
When the interpreter quits, it saves the command history (so quitting by Ctrl-C does not mean a "crash").
In> quit Quitting... |
In> 1+quit Out> quit+1; |
In> restart Out> restart; |
The default operation of Yacas is to run in the interactive console mode. Yacas accepts several options that modify its operation. Here is a summary of options:
Options can be combined, for example
yacas -pc filename |
Here is a more detailed description of the command-line options.
yacas -c |
yacas -f |
yacas -p |
yacas -t |
yacas [options] {filename} |
yacas -v |
yacas -d |
yacas --patchload |
yacas --init [file] |
yacas --read-eval-print [expression] |
There is also a fallback read-eval-print loop in the kernel; it can be invoked by passing an empty string to this command line option, as --read-eval-print "".
An alternative way to replace the default read-eval-print loop is to write a custom initialization script that implements the read-eval-print loop function REP() instead of yacasinit.ys.
Care has to be taken with this option because a Yacas session may become unusable if the read-eval-print expression doesn't function correctly.
yacas --server <port> |
Commands can be sent to the server by sending a text line as one block of data, and the server will respond back with another text block.
One can test this function by using telnet. First, set up the server by calling
yacas --server 9734 |
telnet 127.0.0.1 9734 |
Some security measures and resource management measures have been taken. No more than 10 connections can be alive at any time, a calculation cannot take more than 30 seconds, and Yacas operates in the secure mode, much like calling an expression by passing it as an argument to the Secure function. This means that no system calls are allowed, and no writing to local files, amongst other things. Something that has not been taken care of yet is memory use. A calculation could take up all memory, but not for longer than 30 seconds.
The server is single-threaded, but has persistent sessions for at most 10 users at a time, from which it can service requests in a sequenial order. To make the service multi-threaded, a solution might be to have a proxy in front of the service listening to the port, redirecting it to different processes which get started up for users (this has not been tried yet).
yacas --rootdir [directory] |
yacas --dlldir [directory] |
yacas --archive [file] |
Yacas has an experimental system where files can be compressed into one file, and accessed through this command line option. The advantages are:
An additional savings is due to the fact that the script files are stripped from white spaces and comments, making them smaller and faster loading.
To prepare the compressed library archive, run ./configure with the command line option --enable-archive.
The result should be the archive file scripts.dat. Then launch Yacas with the command line option --archive scripts.dat, with the file scripts.dat in the current directory.
The reason that the scripts.dat file is not built automatically is that it is not tested, at this time, that the build process works on all platforms. (Right now it works on Unix, MacOSX, and Win32.)
Alternatively, configure Yacas with
./configure --enable-archive |
When an archive is present, Yacas will try to load it before it looks for scripts from the library directories. Typing
make archivetest -f makefile.compressor |
The currently supported compression schemes are uncompressed and compressed with minilzo. Script file stripping (removing whitespace and comments) may be disabled by editing compressor.cpp (variable strip_script).
yacas --disable-compiled-plugins |
Disable loading of compiled scripts, in favor of scripts themselves. This is useful when developing the scripts that need to be compiled in the end, or when the scripts have not been compiled yet.
yacas --stacksize <size> |
For a function that would take 4 arguments and has one return value, there would be 5 places reserved on this stack, and the function could call itself recursively 10000 steps deep.
This differs from the MaxEvalDepth mechanism. The MaxEvalDepth mechanism allows one to specify the number of separate stack frames (number of calls, nested), instead of the number of arguments pushed on the stack. MaxEvalDepth was introduced to protect the normal C++ stack.
yacas --execute <expression> |
user% ./yacas -pc --execute '[Echo("answer ",D(x)Sin(x));Exit();]' answer Cos(x) user% |
DefaultDirectory(path) |
Yacas first tries to load a file from the current directory, and otherwise it tries to load from directories defined with this function, in the order they are defined. Note there will be at least one directory specified at start-up time, defined during compilation. This is the directory Yacas searches for the initialization scripts and standard scripts.
In> DefaultDirectory("/home/user/myscripts/"); Out> True; |
DllDirectory(path) |
Note there will be at least one directory specified at start-up time. If the command line option --dlldir is given, the default directory for plugins will be the argument to the option. Otherwise, it is a directory specified at compile time.
This command always evaluates to True.
In> DllDirectory("/home/user/yacas/plugins/"); Out> True; |
PrettyPrinter(printer) PrettyPrinter() GetPrettyPrinter() |
Currently implemented prettyprinters are: PrettyForm, TeXForm, Print, OMForm, CForm and DefaultPrint.
GetPrettyPrinter() returns the current pretty printer, or it returns an empty string if the default pretty printer is used.
In> Taylor(x,0,5)Sin(x) Out> x-x^3/6+x^5/120; In> PrettyPrinter("PrettyForm"); True In> Taylor(x,0,5)Sin(x) 3 5 x x x - -- + --- 6 120 In> PrettyPrinter(); Out> True; In> Taylor(x,0,5)Sin(x) Out> x-x^3/6+x^5/120; |
MaxEvalDepth(n) |
Help() Help(function) |
The function Help is auxiliary and should not be used to actually get online help.
Help(_f) <-- SystemCall("netscape " : FindFile("documentation/ref.html"):"#":f); Help() := SystemCall("netscape " : FindFile("documentation/books.html")); |
HistorySize(n) |
In> HistorySize(200) Out> True; In> quit |
x+y +x |
x-y |
-x x*y |
x/y |
x^y |
These operators are implemented in the standard math library (as opposed to being built-in). This means that they can be extended by the user.
In> 2+3 Out> 5; In> 2*3 Out> 6; |
Div(x,y) Mod(x,y) |
If Div(x,y) returns "a" and Mod(x,y) equals "b", then these numbers satisfy x=a*y+b and 0<=b<y.
In> Div(5,3) Out> 1; In> Mod(5,3) Out> 2; |
Gcd(n,m) Gcd(list) |
list -- a list of all integers or all univariate polynomials
This is a rather fast algorithm on computers that can efficiently shift integers. When factoring Gaussian integers, a slower recursive algorithm is used.
If the second calling form is used, Gcd will return the greatest common divisor of all the integers or polynomials in "list". It uses the identity
In> Gcd(55,10) Out> 5; In> Gcd({60,24,120}) Out> 12; In> Gcd( 7300 + 12*I, 2700 + 100*I) Out> Complex(-4,4); |
Lcm(n,m) Lcm(list) |
This means it also works on polynomials, since Div, Gcd and multiplication are also defined for them.
In> Lcm(60,24) Out> 120; In> Lcm({3,5,7,9}) Out> 315; |
n<<m n>>m |
In> 1 << 10 Out> 1024; In> -1024 >> 10 Out> -1; |
FromBase(base,"string") ToBase(base, number) |
number -- integer, number to write out in a different base
"string" -- string representing a number in a different base
FromBase converts an integer, written as a string in base base, to base 10. ToBase converts number, written in base 10, to base base.
Non-integer arguments are not supported.
In> FromBase(2,"111111") Out> 63; |
Write the (decimal) number 255 in hexadecimal notation:
In> ToBase(16,255) Out> "ff"; |
Precision(n) |
This is not the number of digits after the decimal point. For example, 123.456 has 3 digits after the decimal point and 6 digits of mantissa. The number 123.456 is adequately computed by specifying Precision(6).
The call Precision(n) will not guarantee that all results are precise to n digits.
When the precision is changed, all variables containing previously calculated values remain unchanged. The Precision function only makes all further calculations proceed with a different precision.
Also, when typing floating-point numbers, the current value of Precision is used to implicitly determine the number of precise digits in the number.
In> Precision(10) Out> True; In> N(Sin(1)) Out> 0.8414709848; In> Precision(20) Out> True; In> x:=N(Sin(1)) Out> 0.84147098480789650665; |
The value x is not changed by a Precision() call:
In> [ Precision(10); x; ] Out> 0.84147098480789650665; |
The value x is rounded off to 10 digits after an arithmetic operation:
In> x+0. Out> 0.8414709848; |
In the above operation, 0. was interpreted as a number which is precise to 10 digits (the user does not need to type 0.0000000000 for this to happen). So the result of x+0. is precise only to 10 digits.
GetPrecision() |
In> GetPrecision(); Out> 10; In> Precision(20); Out> True; In> GetPrecision(); Out> 20; |
N(expr) N(expr, prec) |
prec -- integer, precision to use
Application of the N operator will make Yacas calculate floating point representations of functions whenever possible. In addition, the variable Pi is bound to the value of Pi calculated at the current precision. (This value is a "cached constant", so it is not recalculated each time N is used, unless the precision is increased.)
In> 1/2 Out> 1/2; In> N(1/2) Out> 0.5; In> Sin(1) Out> Sin(1); In> N(Sin(1),10) Out> 0.8414709848; In> Pi Out> Pi; In> N(Pi,20) Out> 3.14159265358979323846; |
Rationalize(expr) |
It does this by finding the smallest integer n such that multiplying the number with 10^n is an integer. Then it divides by 10^n again, depending on the internal gcd calculation to reduce the resulting division of integers.
In> {1.2,3.123,4.5} Out> {1.2,3.123,4.5}; In> Rationalize(%) Out> {6/5,3123/1000,9/2}; |
IntLog(n, base) |
This function can also be used to quickly count the digits in a given number.
In> IntLog(257^8, 2) Out> 64; |
Count the number of decimal digits:
In> IntLog(321^321, 10) Out> 804; |
IntNthRoot(x, n) |
This function is used to test numbers for prime powers.
In> IntNthRoot(65537^111, 37) Out> 281487861809153; |
NthRoot(m,n) |
n -- a positive integer greater than 1 ( n>1)
For large m and small n NthRoot may work quite slowly. Every result {f,r} for given m, n is saved in a lookup table, thus subsequent calls to NthRoot with the same values m, n will be executed quite fast.
In> NthRoot(12,2) Out> {2,3}; In> NthRoot(81,3) Out> {3,3}; In> NthRoot(3255552,2) Out> {144,157}; In> NthRoot(3255552,3) Out> {12,1884}; |
ContFrac(x) ContFrac(x, depth) |
depth -- integer, maximum required depth of result
This is especially useful for polynomials, since series expansions that converge slowly will typically converge a lot faster if calculated using a continued fraction expansion.
In> PrettyForm(ContFrac(N(Pi))) 1 --------------------------- + 3 1 ----------------------- + 7 1 ------------------ + 15 1 -------------- + 1 1 -------- + 292 rest + 1 |
Out> True; In> PrettyForm(ContFrac(x^2+x+1, 3)) x ---------------- + 1 x 1 - ------------ x -------- + 1 rest + 1 Out> True; |
ContFracList(frac) ContFracList(frac, depth) ContFracEval(list) ContFracEval(list, rest) |
depth -- desired number of terms
list -- a list of coefficients
rest -- expression to put at the end of the continued fraction
The function ContFracEval converts a list of coefficients into a continued fraction expression. The optional parameter rest specifies the symbol to put at the end of the expansion. If it is not given, the result is the same as if rest=0.
In> A:=ContFracList(33/7 + 0.000001) Out> {4,1,2,1,1,20409,2,1,13,2,1,4,1,1,3,3,2}; In> ContFracEval(Take(A, 5)) Out> 33/7; In> ContFracEval(Take(A,3), remainder) Out> 1/(1/(remainder+2)+1)+4; |
GuessRational(x) GuessRational(x, digits) NearRational(x) NearRational(x, digits) BracketRational(x, eps) |
digits -- desired number of decimal digits (integer)
eps -- desired precision
Unlike the function Rationalize() which converts floating-point numbers to rationals without loss of precision, the functions GuessRational() and NearRational() are intended to find the best rational that is approximately equal to a given value.
The function GuessRational() is useful if you have obtained a floating-point representation of a rational number and you know approximately how many digits its exact representation should contain. This function takes an optional second parameter digits which limits the number of decimal digits in the denominator of the resulting rational number. If this parameter is not given, it defaults to half the current precision. This function truncates the continuous fraction expansion when it encounters an unusually large value (see example). This procedure does not always give the "correct" rational number; a rule of thumb is that the floating-point number should have at least as many digits as the combined number of digits in the numerator and the denominator of the correct rational number.
The function NearRational(x) is useful if one needs to approximate a given value, i.e. to find an "optimal" rational number that lies in a certain small interval around a certain value x. This function takes an optional second parameter digits which has slightly different meaning: it specifies the number of digits of precision of the approximation; in other words, the difference between x and the resulting rational number should be at most one digit of that precision. The parameter digits also defaults to half of the current precision.
The function BracketRational(x,eps) can be used to find approximations with a given relative precision from above and from below. This function returns a list of two rational numbers {r1,r2} such that r1<x<r2 and Abs(r2-r1)<Abs(x*eps). The argument x must be already evaluated to enough precision so that this approximation can be meaningfully found. If the approximation with the desired precision cannot be found, the function returns an empty list.
In> x:=N(956/1013) Out> 0.9437314906 In> Rationalize(x) Out> 4718657453/5000000000; In> V(GuessRational(x)) GuessRational: using 10 terms of the continued fraction Out> 956/1013; In> ContFracList(x) Out> {0,1,16,1,3,2,1,1,1,1,508848,3,1,2,1,2,2}; |
In> NearRational(x) Out> 218/231; |
In> NearRational(x, 10) Out> 956/1013; |
In> BracketRational(N(Ln(10)), 10^(-8)) Out> {12381/5377,41062/17833}; |
Decimal(frac) |
In> Decimal(1/22) Out> {0,0,{4,5}}; In> N(1/22,30) Out> 0.045454545454545454545454545454; |
TruncRadian(r) |
The library uses the formula
In> 2*Pi() Out> 6.283185307; In> TruncRadian(6.28) Out> 6.28; In> TruncRadian(6.29) Out> 0.0068146929; |
Floor(x) |
In> Floor(1.1) Out> 1; In> Floor(-1.1) Out> -2; |
Ceil(x) |
In> Ceil(1.1) Out> 2; In> Ceil(-1.1) Out> -1; |
Round(x) |
In> Round(1.49) Out> 1; In> Round(1.51) Out> 2; In> Round(-1.49) Out> -1; In> Round(-1.51) Out> -2; |
Pslq(xlist,precision) |
precision -- required number of digits precision of calculation
The numbers in "xlist" must evaluate to floating point numbers if the N operator is applied on them.
In> Pslq({ 2*Pi+3*Exp(1), Pi, Exp(1) },20) Out> {1,-2,-3}; |
Note: in this example the system detects correctly that 1*(2*Pi+3*e)+(-2)*Pi+(-3)*e=0.
IsPrime(n) IsSmallPrime(n) |
The function IsShortPrime only works for numbers n<=65537 but it is very fast.
The function IsPrime operates on all numbers and uses different algorithms depending on the magnitude of the number n. For small numbers n<=65537, a constant-time table lookup is performed. (The function IsShortPrime is used for that.) For numbers n between 65537 and 34155071728321, the function uses the Rabin-Miller test together with table lookups to guarantee correct results.
For even larger numbers a version of the probabilistic Rabin-Miller test is executed. The test can sometimes mistakenly mark a number as prime while it is in fact composite, but a prime number will never be mistakenly declared composite. The parameters of the test are such that the probability for a false result is less than 10^(-24).
In> IsPrime(1) Out> False; In> IsPrime(2) Out> True; In> IsPrime(10) Out> False; In> IsPrime(23) Out> True; In> Select("IsPrime", 1 .. 100) Out> {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47, 53,59,61,67,71,73,79,83,89,97}; |
IsComposite(n) |
In> IsComposite(1) Out> False; In> IsComposite(7) Out> False; In> IsComposite(8) Out> True; In> Select(IsComposite,1 .. 20) Out> {4,6,8,9,10,12,14,15,16,18,20}; |
IsCoprime(m,n) IsCoprime(list) |
list -- list of positive integers
In> IsCoprime({3,4,5,8}) Out> False; In> IsCoprime(15,17) Out> True; |
IsSquareFree(n) |
In> IsSquareFree(37) Out> True; In> IsSquareFree(4) Out> False; In> IsSquareFree(16) Out> False; In> IsSquareFree(18) Out> False; |
IsPrimePower(n) |
This function does not try to decompose the number n into factors. Instead we check for all prime numbers r=2, 3, ... that the r-th root of n is an integer, and we find such r and m that n=m^r, we check that m is a prime. If it is not a prime, we execute the same function call on m.
In> IsPrimePower(9) Out> True; In> IsPrimePower(10) Out> False; In> Select("IsPrimePower", 1 .. 50) Out> {2,3,4,5,7,8,9,11,13,16,17,19,23,25,27, 29,31,32,37,41,43,47,49}; |
NextPrime(i) |
The routine generates "candidate numbers" using the formula n+2*Mod(-n,3) where n is an odd number (this generates the sequence 5, 7, 11, 13, 17, 19, ...) and IsPrime() to test whether the next candidate number is in fact prime.
In> NextPrime(5) Out> 7; |
IsTwinPrime(n) |
In> IsTwinPrime(101) Out> True; In> IsTwinPrime(7) Out> False; In> Select(IsTwinPrime, 1 .. 100) Out> {3,5,11,17,29,41,59,71}; |
IsIrregularPrime(n) |
In> IsIrregularPrime(5) Out> False; In> Select(IsIrregularPrime,1 .. 100) Out> {37,59,67}; |
IsCarmichaelNumber(n) |
In> IsCarmichaelNumber(561) Out> True; In> Time(Select(IsCarmichaelNumber,1 .. 10000)) 504.19 seconds taken Out> {561,1105,1729,2465,2821,6601,8911}; |
Factors(x) |
The factorization is returned as a list of pairs. The first member of each pair is the factor, while the second member denotes the power to which this factor should be raised. So the factorization x=p1^n1*...*p9^n9 is returned as {{p1,n1}, ..., {p9,n9}}.
In> Factors(24); Out> {{2,3},{3,1}}; In> Factors(2*x^3 + 3*x^2 - 1); Out> {{2,1},{x+1,2},{x-1/2,1}}; |
IsAmicablePair(m,n) |
In> IsAmicablePair(200958394875, 209194708485 ) Out> True; In> IsAmicablePair(220, 284) Out> True; |
Factor(x) |
In> PrettyForm(Factor(24)); 3 2 * 3 Out> True; In> PrettyForm(Factor(2*x^3 + 3*x^2 - 1)); 2 / 1 \ 2 * ( x + 1 ) * | x - - | \ 2 / Out> True; |
Divisors(n) |
In> Divisors(180) Out> 18; In> Divisors(37) Out> 2; |
DivisorsSum(n) |
In> DivisorsSum(180) Out> 546; In> DivisorsSum(37) Out> 38; |
ProperDivisors(n) |
In> ProperDivisors(180) Out> 17; In> ProperDivisors(37) Out> 1; |
ProperDivisorsSum(n) |
In> ProperDivisorsSum(180) Out> 366; In> ProperDivisorsSum(37) Out> 1; |
Moebius(n) |
In> Moebius(10) Out> 1; In> Moebius(11) Out> -1; In> Moebius(12) Out> 0; In> Moebius(13) Out> -1; |
CatalanNumber(n) |
In> CatalanNumber(10) Out> 16796; In> CatalanNumber(5) Out> 42; |
FermatNumber(n) |
In> FermatNumber(7) Out> 340282366920938463463374607431768211457; |
HarmonicNumber(n) HarmonicNumber(n,r) |
In> HarmonicNumber(10) Out> 7381/2520; In> HarmonicNumber(15) Out> 1195757/360360; In> HarmonicNumber(1) Out> 1; In> HarmonicNumber(4,3) Out> 2035/1728; |
StirlingNumber1(n,m) |
In> StirlingNumber1(10,5) Out> -269325; In> StirlingNumber1(3,6) Out> 0; |
In> StirlingNumber2(3,6) Out> 0; In> StirlingNumber2(10,4) Out> 34105; |
DivisorsList(n) |
ForEach(d,DivisorsList(n)) |
In> DivisorsList(18) Out> {1,2,3,6,9,18}; |
SquareFreeDivisorsList(n) |
In> SquareFreeDivisorsList(18) Out> {1,2,3,6}; |
MoebiusDivisorsList(n) |
In> MoebiusDivisorsList(18) Out> {{1,1},{2,-1},{3,-1},{6,1}}; |
SumForDivisors(var,n,expr) |
n -- positive integer
expr -- expression depending on var
RamanujanSum(k,n) |
where l runs thought the integers between 1 and k-1 that are coprime to l.
The computation is done by using the formula in T. M. Apostol, Introduction to Analytic Theory (Springer-Verlag), Theorem 8.6.
Cyclotomic(n,x) |
x -- variable
For n even, we write n=m*k, where k is a power of 2 and m is odd, and reduce it to the case of even m since
If m=1, n is a power of 2, and Cyclotomic(n,x)=x^k+1.
For n odd, the algorithm is based on the formula
PAdicExpand(n, p) |
p -- base to expand in
In> PrettyForm(PAdicExpand(1234, 10)); 2 3 3 * 10 + 2 * 10 + 10 + 4 Out> True; In> PrettyForm(PAdicExpand(x^3, x-1)); 2 3 3 * ( x - 1 ) + 3 * ( x - 1 ) + ( x - 1 ) + 1 Out> True; |
IsQuadraticResidue(m,n) LegendreSymbol(m,n) JacobiSymbol(m,n) |
The Legendre symbol (m/ n) is defined as +1 if m is a quadratic residue modulo n and -1 if it is a non-residue. The Legendre symbol is equal to 0 if m/n is an integer.
The Jacobi symbol [m/n;] is defined as the product of the Legendre symbols of the prime factors f[i] of n=f[1]^p[1]*...*f[s]^p[s],
The Jacobi symbol can be efficiently computed without knowing the full factorization of the number n.
In> IsQuadraticResidue(9,13) Out> True; In> LegendreSymbol(15,23) Out> -1; In> JacobiSymbol(7,15) Out> -1; |
GaussianFactors(z) |
The factorization is returned as a list of pairs. The first member of each pair is the factor (a Gaussian integer) and the second member denotes the power to which this factor should be raised. So the factorization is returned as a list, e.g. {{p1,n1}, {p2,n2}, ...}.
In> GaussianFactors(5) Out> {{Complex(2,1),1},{Complex(2,-1),1}}; In> GaussianFactors(3+I) Out> {{Complex(1,1),1},{Complex(2,-1),1}}; |
GaussianNorm(z) |
In> GaussianNorm(2+I) Out> 5; |
IsGaussianUnit(z) |
There are four "units" in the ring of Gaussian integers, which are 1, -1, I, and -I.
In> IsGaussianInteger(I) Out> True; In> IsGaussianUnit(5+6*I) Out> False; |
IsGaussianPrime(z) |
A prime element x of a ring is divisible only by the units of the ring and by associates of x. ("Associates" of x are elements of the form x*u where u is a unit of the ring).
Gaussian primes are Gaussian integers z=a+b*I that satisfy one of the following properties:
In> IsGaussianPrime(13) Out> False; In> IsGaussianPrime(2+2*I) Out> False; In> IsGaussianPrime(2+3*I) Out> True; In> IsGaussianPrime(3) Out> True; |
GaussianGcd(z,w) |
In> GaussianGcd(2+I,5) Out> Complex(2,1); |
In> GaussianGcd(2+I,3+I) Out> -1; |
Sin(x) Cos(x) Tan(x) |
Yacas knows some trigonometric identities, so it can simplify to exact results even if N is not used. This is the case, for instance, when the argument is a multiple of Pi/6 or Pi/4.
These functions are threaded, meaning that if the argument x is a list, the function is applied to all entries in the list.
In> Sin(1) Out> Sin(1); In> N(Sin(1),20) Out> 0.84147098480789650665; In> Sin(Pi/4) Out> Sqrt(2)/2; |
ArcSin(x) ArcCos(x) ArcTan(x) |
Note that the number y is not unique. For instance, Sin(0) and Sin(Pi) both equal 0, so what should ArcSin(0) be? In Yacas, it is agreed that the value of ArcSin(x) should be in the interval [-Pi/2, Pi/2]. The same goes for ArcTan(x). However, ArcCos(x) is in the interval [0,Pi].
Usually, Yacas leaves these functions alone unless it is forced to do a numerical evaluation by the N function. If the argument is -1, 0, or 1 however, Yacas will simplify the expression. If the argument is complex, the expression will be rewritten using the Ln function.
These functions are threaded, meaning that if the argument x is a list, the function is applied to all entries in the list.
In> ArcSin(1) Out> Pi/2; In> ArcSin(1/3) Out> ArcSin(1/3); In> Sin(ArcSin(1/3)) Out> 1/3; In> x:=N(ArcSin(0.75)) Out> 0.848062; In> N(Sin(x)) Out> 0.7499999477; |
Exp(x) |
This function is threaded, meaning that if the argument x is a list, the function is applied to all entries in the list.
In> Exp(0) Out> 1; In> Exp(I*Pi) Out> -1; In> N(Exp(1)) Out> 2.7182818284; |
Ln(x) |
This function is threaded, meaning that if the argument x is a list, the function is applied to all entries in the list.
In> Ln(1) Out> 0; In> Ln(Exp(x)) Out> x; In> D(x) Ln(x) Out> 1/x; |
Sqrt(x) |
This function is threaded, meaning that if the argument x is a list, the function is applied to all entries in the list.
In> Sqrt(16) Out> 4; In> Sqrt(15) Out> Sqrt(15); In> N(Sqrt(15)) Out> 3.8729833462; In> Sqrt(4/9) Out> 2/3; In> Sqrt(-1) Out> Complex(0,1); |
Abs(x) |
This function is connected to the Sign function by the identity "Abs(x) * Sign(x) = x" for real "x".
This function is threaded, meaning that if the argument x is a list, the function is applied to all entries in the list.
In> Abs(2); Out> 2; In> Abs(-1/2); Out> -1/2; In> Abs(3+4*I); Out> 5; |
Sign(x) |
This function is connected to the Abs function by the identity Abs(x)*Sign(x)=x for real x.
This function is threaded, meaning that if the argument x is a list, the function is applied to all entries in the list.
In> Sign(2) Out> 1; In> Sign(-3) Out> -1; In> Sign(0) Out> 1; In> Sign(-3) * Abs(-3) Out> -3; |
Complex(r, c) |
c -- imaginary part
Note that, at the moment, many functions in Yacas assume that all numbers are real unless it is obvious that it is a complex number. Hence Im(Sqrt(x)) evaluates to 0 which is only true for nonnegative "x".
In> I Out> Complex(0,1); In> 3+4*I Out> Complex(3,4); In> Complex(-2,0) Out> -2; |
Re(x) |
In> Re(5) Out> 5; In> Re(I) Out> 0; In> Re(Complex(3,4)) Out> 3; |
Im(x) |
In> Im(5) Out> 0; In> Im(I) Out> 1; In> Im(Complex(3,4)) Out> 4; |
I |
In> I Out> Complex(0,1); In> I = Sqrt(-1) Out> True; |
Conjugate(x) |
In> Conjugate(2) Out> 2; In> Conjugate(Complex(a,b)) Out> Complex(a,-b); |
Arg(x) |
In> Arg(2) Out> 0; In> Arg(-1) Out> Pi; In> Arg(1+I) Out> Pi/4; |
RootsOfUnity(n) |
In> RootsOfUnity(3) Out> {Complex(-1/2,Sqrt(3/4)),Complex(-1/2,-Sqrt(3/4)),1}; In> RootsOfUnity(1) Out> {1}; In> RootsOfUnity(2) Out> {-1,1}; |
n! n!! a *** b Subfactorial(m) |
The "double factorial" function n!! calculates n*(n-2)*(n-4)*.... This product terminates either with 1 or with 2 depending on whether n is odd or even. If n=0 the function returns 1.
The "partial factorial" function a *** b calculates the product a*(a+1)*... which is terminated at the least integer not greater than b. The arguments a and b do not have to be integers; for integer arguments, a *** b = b! /(a-1)!. This function is sometimes a lot faster than evaluating the two factorials, especially if a and b are close together. If a>b the function returns 1.
The Subfactorial function can be interpreted as the number of permutations of m objects in which no object appears in its natural place, also called "derangements."
The factorial functions are threaded, meaning that if the argument n is a list, the function will be applied to each element of the list.
Note: For reasons of Yacas syntax, the factorial sign ! cannot precede other non-letter symbols such as + or *. Therefore, you should enter a space after ! in expressions such as x! +1.
The factorial functions terminate and print an error message if the arguments are too large (currently the limit is n<65535) because exact factorials of such large numbers are computationally expensive and most probably not useful. One can call LnGammaNum() to evaluate logarithms of such factorials to desired precision.
In> 5! Out> 120; In> 1 * 2 * 3 * 4 * 5 Out> 120; In> (1/2)! Out> Sqrt(Pi)/2; In> 7!!; Out> 105; In> 1/3 *** 10; Out> 17041024000/59049; In> Subfactorial(10) Out> 1334961; |
Bin(n, m) |
This is equal to the number of ways to choose "m" objects out of a total of "n" objects if order is not taken into account. The binomial coefficient is defined to be zero if "m" is negative or greater than "n"; Bin(0,0)=1.
In> Bin(10, 4) Out> 210; In> 10! / (4! * 6!) Out> 210; |
Eulerian(n,m) |
In> Eulerian(6,2) Out> 302; In> Eulerian(10,9) Out> 1; |
Add(val1, val2, ...) Add({list}) |
{list} -- list of expressions to add
In> Add(1,4,9); Out> 14; In> Add(1 .. 10); Out> 55; |
Sum(var, from, to, body) |
from -- integer value to iterate from
to -- integer value to iterate up to
body -- expression to evaluate for each iteration
Warning: Sum does not evaluate its arguments var and body until the actual loop is run.
In> Sum(i, 1, 3, i^2); Out> 14; |
Average(list) |
In> Average({1,2,3,4,5}); Out> 3; In> Average({2,6,7}); Out> 5; |
Factorize(list) Factorize(var, from, to, body) |
var -- variable to iterate over
from -- integer value to iterate from
to -- integer value to iterate up to
body -- expression to evaluate for each iteration
If the second calling sequence is used, the expression "body" is evaluated while the variable "var" ranges over all integers from "from" up to "to", and the product of all the results is returned. Obviously, "to" should be greater than or equal to "from".
In> Factorize({1,2,3,4}); Out> 24; In> Factorize(i, 1, 4, i); Out> 24; |
Min(x,y) Min(list) |
list -- list of values from which the minimum is sought
In> Min(2,3); Out> 2; In> Min({5,8,4}); Out> 4; |
Max(x,y) Max(list) |
list -- list of values from which the maximum is sought
In> Max(2,3); Out> 3; In> Max({5,8,4}); Out> 8; |
IsZero(n) |
In> IsZero(3.25) Out> False; In> IsZero(0) Out> True; In> IsZero(x) Out> False; |
IsRational(expr) |
In> IsRational(5) Out> False; In> IsRational(2/7) Out> True; In> IsRational(0.5) Out> False; In> IsRational(a/b) Out> False; In> IsRational(x + 1/x) Out> False; |
Numer(expr) |
In> Numer(2/7) Out> 2; In> Numer(a / x^2) Out> a; In> Numer(5) Out> 5; |
Denom(expr) |
In> Denom(2/7) Out> 7; In> Denom(a / x^2) Out> x^2; In> Denom(5) Out> 1; |
Commutator(a, b) |
In> Commutator(2,3) Out> 0; In> PrettyPrinter("PrettyForm"); True In> A := { {0,x}, {0,0} } / \ | ( 0 ) ( x ) | | | | ( 0 ) ( 0 ) | \ / In> B := { {y,0}, {0,z} } / \ | ( y ) ( 0 ) | | | | ( 0 ) ( z ) | \ / In> Commutator(A,B) / \ | ( 0 ) ( x * z - y * x ) | | | | ( 0 ) ( 0 ) | \ / |
Taylor(var, at, order) expr |
at -- point to get Taylor series around
order -- order of approximation
expr -- expression to get Taylor series for
In> PrettyForm(Taylor(x,0,9) Sin(x)) 3 5 7 9 x x x x x - -- + --- - ---- + ------ 6 120 5040 362880 Out> True; |
InverseTaylor(var, at, order) expr |
at -- point to get inverse Taylor series around
order -- order of approximation
expr -- expression to get inverse Taylor series for
In> PrettyPrinter("PrettyForm") True In> exp1 := Taylor(x,0,7) Sin(x) 3 5 7 x x x x - -- + --- - ---- 6 120 5040 In> exp2 := InverseTaylor(x,0,7) ArcSin(x) 5 7 3 x x x --- - ---- - -- + x 120 5040 6 In> Simplify(exp1-exp2) 0 |
ReversePoly(f, g, var, newvar, degree) |
var -- a variable
newvar -- a new variable to express the result in
degree -- the degree of the required solution
This function is used to determine the Taylor series expansion of the inverse of a function "f": if we take "g(var)=var", then "h(f(var))=var" (up to order "degree"), so "h" will be the inverse of "f".
In> f(x):=Eval(Expand((1+x)^4)) Out> True; In> g(x) := x^2 Out> True; In> h(y):=Eval(ReversePoly(f(x),g(x),x,y,8)) Out> True; In> BigOh(h(f(x)),x,8) Out> x^2; In> h(x) Out> (-2695*(x-1)^7)/131072+(791*(x-1)^6) /32768 +(-119*(x-1)^5)/4096+(37*(x-1)^4) /1024+(-3*(x-1)^3)/64+(x-1)^2/16; |
BigOh(poly, var, degree) |
var -- a free variable
degree -- positive integer
In> BigOh(1+x+x^2+x^3,x,2) Out> x+1; |
Newton(expr, var, initial, accuracy) Newton(expr, var, initial, accuracy,min,max) |
var -- free variable to adjust to find a zero
initial -- initial value for "var" to use in the search
accuracy -- minimum required accuracy of the result
min -- minimum value for "var" to use in the search
max -- maximum value for "var" to use in the search
The function will iterate using Newton's method until it estimates that it has come within a distance accuracy of the correct solution, and then it will return its best guess. In particular, it may loop forever if the algorithm does not converge.
When min and max are supplied, the Newton iteration takes them into account by returning Fail if it failed to find a root in the given range. Note this doesn't mean there isn't a root, just that this algorithm failed to find it due to the trial values going outside of the bounds.
In> Newton(Sin(x),x,3,0.0001) Out> 3.1415926535; In> Newton(x^2-1,x,2,0.0001,-5,5) Out> 1; In> Newton(x^2+1,x,2,0.0001,-5,5) Out> Fail; |
D(var) expr D(list) expr D(var,n) expr |
list -- a list of variables
expr -- expression to take derivatives of
n -- order of derivative
The D operator is threaded in both var and expr. This means that if either of them is a list, the function is applied to each entry in the list. The results are collected in another list which is returned. If both var and expr are a list, their lengths should be equal. In this case, the first entry in the list expr is differentiated with respect to the first entry in the list var, the second entry in expr is differentiated with respect to the second entry in var, and so on.
The D operator returns the original function if n=0, a common mathematical idiom that simplifies many formulae.
In> D(x)Sin(x*y) Out> y*Cos(x*y); In> D({x,y,z})Sin(x*y) Out> {y*Cos(x*y),x*Cos(x*y),0}; In> D(x,2)Sin(x*y) Out> -Sin(x*y)*y^2; In> D(x){Sin(x),Cos(x)} Out> {Cos(x),-Sin(x)}; |
Curl(vector, basis) |
basis -- list of variables forming the basis
Curl(f,x) = { D(x[2]) f[3] - D(x[3]) f[2], D(x[3]) f[1] - D(x[1]) f[3], D(x[1]) f[2] - D(x[2]) f[1] } |
In> Curl({x*y,x*y,x*y},{x,y,z}) Out> {x,-y,y-x}; |
Diverge(vector, basis) |
basis -- list of variables forming the basis
Diverge(f,x) = D(x[1]) f[1] + ... + D(x[n]) f[n], |
In> Diverge({x*y,x*y,x*y},{x,y,z}) Out> y+x; |
Integrate(var, x1, x2) expr Integrate(var) expr |
x1 -- first point of definite integration
x2 -- second point of definite integration
expr -- expression to integrate
Some simple integration rules have currently been implemented. Polynomials, some quotients of polynomials, trigonometric functions and their inverses, hyperbolic functions and their inverses, Exp, and Ln, and products of these functions with polynomials can be integrated.
In> Integrate(x,a,b) Cos(x) Out> Sin(b)-Sin(a); In> Integrate(x) Cos(x) Out> Sin(x); |
Simplify(expr) |
In> a*b*a^2/b-a^3 Out> (b*a^3)/b-a^3; In> Simplify(a*b*a^2/b-a^3) Out> 0; |
RadSimp(expr) |
It does this by trying all possible combinations for e1, e2, ... Every possibility is numerically evaluated using N and compared with the numerical evaluation of "expr". If the approximations are equal (up to a certain margin), this possibility is returned. Otherwise, the expression is returned unevaluated.
Note that due to the use of numerical approximations, there is a small chance that the expression returned by RadSimp is close but not equal to expr. The last example underneath illustrates this problem. Furthermore, if the numerical value of expr is large, the number of possibilities becomes exorbitantly big so the evaluation may take very long.
In> RadSimp(Sqrt(9+4*Sqrt(2))) Out> Sqrt(8)+1; In> RadSimp(Sqrt(5+2*Sqrt(6)) \ +Sqrt(5-2*Sqrt(6))) Out> Sqrt(12); In> RadSimp(Sqrt(14+3*Sqrt(3+2 *Sqrt(5-12*Sqrt(3-2*Sqrt(2)))))) Out> Sqrt(2)+3; |
But this command may yield incorrect results:
In> RadSimp(Sqrt(1+10^(-6))) Out> 1; |
FactorialSimplify(expression) |
The following steps are taken to simplify:
The function Simplify is used to determine if the relevant expressions n-m are integers.
In> FactorialSimplify( (n-k+1)! / (n-k)! ) Out> n+1-k In> FactorialSimplify(n! / Bin(n,k)) Out> k! *(n-k)! In> FactorialSimplify(2^(n+1)/2^n) Out> 2 |
LnExpand(expr) |
If the logarithm of an integer is discovered, it is factorised using Factors and expanded as though LnExpand had been given the factorised form. So Ln(18) goes to Ln(x)+2*Ln(3).
In> LnExpand(Ln(a*b^n)) Out> Ln(a)+Ln(b)*n In> LnExpand(Ln(a^m/b^n)) Out> Ln(a)*m-Ln(b)*n In> LnExpand(Ln(60)) Out> 2*Ln(2)+Ln(3)+Ln(5) In> LnExpand(Ln(60/25)) Out> 2*Ln(2)+Ln(3)-Ln(5) |
LnCombine(expr) |
In> LnCombine(Ln(a)+Ln(b)*n) Out> Ln(a*b^n) In> LnCombine(2*Ln(2)+Ln(3)-Ln(5)) Out> Ln(12/5) |
Rationalize(expr) |
It does this by finding the smallest integer n such that multiplying the number with 10^n is an integer. Then it divides by 10^n again, depending on the internal gcd calculation to reduce the resulting division of integers.
In> x:={1.2, 3.123, 4.5} Out> {1.2,3.123,4.5}; In> Rationalize(x) Out> {6/5,3123/1000,9/2}; |
Solve(eq, var) |
var -- variable to solve for
The current implementation is far from perfect. In particular, the user should keep the following points in mind:
In> quadratic := x^2+x; Out> x^2+x; In> Solve(quadratic, x); Out> {x==0,x==(-1)}; In> quadratic Where %; Out> {0,0}; |
If one tries to solve the equation Exp(x)==Sin(x), one finds that Solve can not do this.
In> PrettyPrinter("DefaultPrint"); Out> True; In> Solve(Exp(x) == Sin(x), x); Error: Solve'Fails: cannot solve equation Exp(x)-Sin(x) for x Out> {}; |
The equation Cos(x)==1/2 has an infinite number of solutions, namely x==(2*k+1/3)*Pi and x==(2*k-1/3)*Pi for any integer k. However, Solve only reports the solutions with k==0.
In> Solve(Cos(x) == 1/2, x); Out> {x==Pi/3,x== -Pi/3}; |
For the equation x/Sin(x)==0, a spurious solution at x==0 is returned. However, the fraction is undefined at that point.
In> Solve(x / Sin(x) == 0, x); Out> {x==0}; |
At first sight, the equation Sqrt(x)==a seems to have the solution x==a^2. However, this is not true for eg. a== -1.
In> PrettyPrinter("DefaultPrint"); Out> True; In> Solve(Sqrt(x) == a, x); Error: Solve'Fails: cannot solve equation Sqrt(x)-a for x Out> {}; In> Solve(Sqrt(x) == 2, x); Out> {x==4}; In> Solve(Sqrt(x) == -1, x); Out> {}; |
OldSolve(eq, var) OldSolve(eqlist, varlist) |
var -- single variable
eqlist -- list of identity equations
varlist -- list of variables
This command tries to solve one or more equations. Use the first form to solve a single equation and the second one for systems of equations.
The first calling sequence solves the equation "eq" for the variable "var". Use the == operator to form the equation. The value of "var" which satisfies the equation, is returned. Note that only one solution is found and returned.
To solve a system of equations, the second form should be used. It solves the system of equations contained in the list "eqlist" for the variables appearing in the list "varlist". A list of results is returned, and each result is a list containing the values of the variables in "varlist". Again, at most a single solution is returned.
The task of solving a single equation is simply delegated to SuchThat. Multiple equations are solved recursively: firstly, an equation is sought in which one of the variables occurs exactly once; then this equation is solved with SuchThat; and finally the solution is substituted in the other equations by Eliminate decreasing the number of equations by one. This suffices for all linear equations and a large group of simple nonlinear equations.
In> OldSolve(a+x*y==z,x) Out> (z-a)/y; In> OldSolve({a*x+y==0,x+z==0},{x,y}) Out> {{-z,z*a}}; |
This means that "x = (z-a)/y" is a solution of the first equation and that "x = -z", "y = z*a" is a solution of the systems of equations in the second command.
An example which OldSolve cannot solve:
In> OldSolve({x^2-x == y^2-y,x^2-x == y^3+y},{x,y}); Out> {}; |
SuchThat(expr, var) |
var -- variable (or subexpression) to solve for
Basically, only expressions in which "var" occurs only once are handled; in fact, SuchThat may even give wrong results if the variables occurs more than once. This is a consequence of the implementation, which repeatedly applies the inverse of the top function until the variable "var" is reached.
In> SuchThat(a+b*x, x) Out> (-a)/b; In> SuchThat(Cos(a)+Cos(b)^2, Cos(b)) Out> Cos(a)^(1/2); In> A:=Expand(a*x+b*x+c, x) Out> (a+b)*x+c; In> SuchThat(A, x) Out> (-c)/(a+b); |
Eliminate(var, value, expr) |
value -- new value of "var"
expr -- expression in which the substitution should take place
In> Subst(Cos(b), c) (Sin(a)+Cos(b)^2/c) Out> Sin(a)+c^2/c; In> Eliminate(Cos(b), c, Sin(a)+Cos(b)^2/c) Out> Sin(a)+c; |
PSolve(poly, var) |
var -- a variable
In> PSolve(b*x+a,x) Out> -a/b; In> PSolve(c*x^2+b*x+a,x) Out> {(Sqrt(b^2-4*c*a)-b)/(2*c),(-(b+ Sqrt(b^2-4*c*a)))/(2*c)}; |
Pi() |
In> Pi() Out> 3.14159265358979323846; In> Sin(3*Pi/2) Out> -1; In> Sin(3*Pi()/2) Out> Sin(4.7123889804); In> Precision(35) Out> True; In> Pi() Out> 3.14159265358979323846264338327950288; |
Random() RandomSeed(init) |
*PARAMS init -- positive integer, initial random seed
The random number generator can be initialized by calling RandomSeed with an integer value. Each seed value will result in the same sequence of pseudo-random numbers.
RngCreate() RngCreate(init) RngCreate(option=value,...) RngSeed(r, init) Rng(r) |
option -- atom, option name
value -- atom, option value
r -- a list, RNG object
RngCreate returns a list which is a well-formed RNG object. Its value should be saved in a variable and used to call Rng and RngSeed.
Rng(r) returns a floating-point random number between 0 and 1 and updates the RNG object r. (Currently, the Gaussian option makes a RNG return a complex random number instead of a real random number.)
RngSeed(r,init) re-initializes the RNG object r with the seed value init. The seed value should be a positive integer.
The RngCreate function accepts several options as arguments. Currently the following options are available:
If the initial seed is not specified, the value of 76544321 will be used.
The gauss option will create a RNG object that generates pairs of Gaussian distributed random numbers as a complex random number. The real and the imaginary parts of this number are independent random numbers taken from a Gaussian (i.e. "normal") distribution with unit variance.
Note that unlike the global Random function, the RNG objects created with RngCreate are independent RNGs and do not affect each other. They generate independent streams of pseudo-random numbers. However, the Random function is slightly faster.
In> r1:=RngCreate(seed=1,dist=gauss) Out> {"GaussianRNGDist","RNGEngine'LCG'2",{1}} In> Rng(r1) Out> Complex(-1.6668466417,0.228904004); In> Rng(r1); Out> Complex(0.0279296109,-0.5382405341); |
In> [r2:=RngCreate(engine=advanced);Rng(r2);] Out> 0.3653615377; |
In> RngSeed(r1, 1) Out> True; In> Rng(r1) Out> Complex(-1.6668466417,0.228904004); |
Limit(var, val) expr Limit(var, val, dir) expr |
val -- a number
dir -- a direction (Left or Right)
expr -- an expression
The second calling sequence is used for unidirectional limits. If one gives "dir" the value Left, the limit is taken as "var" approaches "val" from the positive infinity; and Right will take the limit from the negative infinity.
In> Limit(x,0) Sin(x)/x Out> 1; In> Limit(x,0) (Sin(x)-Tan(x))/(x^3) Out> -1/2; In> Limit(x,0) 1/x Out> Undefined; In> Limit(x,0,Left) 1/x Out> -Infinity; In> Limit(x,0,Right) 1/x Out> Infinity; |
TrigSimpCombine(expr) |
This function is used in for instance Integrate, to bring down the expression into a simpler form that hopefully can be integrated easily.
In> PrettyPrinter("PrettyForm"); True In> TrigSimpCombine(Cos(a)^2+Sin(a)^2) 1 In> TrigSimpCombine(Cos(a)^2-Sin(a)^2) Cos( -2 * a ) Out> In> TrigSimpCombine(Cos(a)^2*Sin(b)) Sin( b ) Sin( -2 * a + b ) -------- + ----------------- 2 4 Sin( -2 * a - b ) - ----------------- 4 |
LagrangeInterpolant(xlist, ylist, var) |
ylist -- list of function values
var -- free variable for resulting polynomial
The lists "xlist" and "ylist" should be of equal length. Furthermore, the entries of "xlist" should be all distinct to ensure that there is one and only one solution.
This routine uses the Lagrange interpolant formula to build up the polynomial.
In> f := LagrangeInterpolant({0,1,2}, \ {0,1,1}, x); Out> (x*(x-1))/2-x*(x-2); In> Eval(Subst(x,0) f); Out> 0; In> Eval(Subst(x,1) f); Out> 1; In> Eval(Subst(x,2) f); Out> 1; In> PrettyPrinter("PrettyForm"); True In> LagrangeInterpolant({x1,x2,x3}, {y1,y2,y3}, x) y1 * ( x - x2 ) * ( x - x3 ) ---------------------------- ( x1 - x2 ) * ( x1 - x3 ) y2 * ( x - x1 ) * ( x - x3 ) + ---------------------------- ( x2 - x1 ) * ( x2 - x3 ) y3 * ( x - x1 ) * ( x - x2 ) + ---------------------------- ( x3 - x1 ) * ( x3 - x2 ) |
Fibonacci(n) |
The Fibonacci sequence is 1, 1, 2, 3, 5, 8, 13, 21, ... where every number is the sum of the two preceding numbers. Formally, it is defined by F(1)=1, F(2)=1, and F(n+1)=F(n)+F(n-1), where F(n) denotes the n-th Fibonacci number.
In> Fibonacci(4) Out> 3; In> Fibonacci(8) Out> 21; In> Table(Fibonacci(i), i, 1, 10, 1) Out> {1,1,2,3,5,8,13,21,34,55}; |
Gamma(x) GammaNum(number) |
number -- expression that can be evaluated to a number
Note that Euler's constant gamma<=>0.57722 is the lowercase gamma in Yacas.
In> Precision(30) Out> True; In> Gamma(1.3) Out> Gamma(1.3); In> N(Gamma(1.3)) Out> 0.897470696306277188493754954771; In> Gamma(1.5) Out> Sqrt(Pi)/2; In> GammaNum(1.5); Out> 0.88622692545275801364908374167; |
Zeta(x) ZetaNum(number) |
number -- expression that can be evaluated to a number
In> Precision(30) Out> True; In> Zeta(1) Out> Infinity; In> Zeta(1.3) Out> Zeta(1.3); In> N(Zeta(1.3)) Out> 3.93194921180954422697490751058798; In> Zeta(2) Out> Pi^2/6; In> ZetaNum(2); Out> 1.64493406684822643647241516664602; |
Bernoulli(index) BernoulliArray(index) Bernoulli(index, x) |
index -- expression that can be evaluated to an integer
An auxiliary function BernoulliArray(n) might be useful too: it returns an array (of type GenericArray) of Bernoulli numbers up to n. The array is 1-based, so that the n-th Bernoulli number is BernoulliArray(n)[n+1].
In> Bernoulli(20); Out> -174611/330; In> Bernoulli(4, x); Out> ((x-2)*x+1)*x^2-1/30; |
Euler(index) Euler(index,x) |
index -- expression that can be evaluated to an integer
In> Euler(6) Out> -61; In> A:=Euler(5,x) Out> (x-1/2)^5+(-10*(x-1/2)^3)/4+(25*(x-1/2))/16; In> Simplify(A) Out> (2*x^5-5*x^4+5*x^2-1)/2; |
LambertW(x) LambertWNum(x) |
For real arguments x, W(x) is real if x>= -Exp(-1).
LambertWNum is an auxiliary function that computes the numerical value of the principal branch of Lambert's W function for real arguments x>= -Exp(-1) to current precision.
In> LambertW(0) Out> 0; In> N(LambertW(-0.24/Sqrt(3*Pi))) Out> -0.0851224014; |
N(gamma) gamma() |
The constant is available symbolically as gamma or numerically as a function gamma(). This is a "cached constant" which is recalculated only when precision is increased. The numerical value of the constant can also be obtained as N(gamma). The low-level numerical computations are performed by the routine GammaConstNum.
Note that Euler's Gamma function Gamma(x) is the capitalized Gamma in Yacas.
In> gamma+Pi Out> gamma+Pi; In> N(gamma+Pi) Out> 3.7188083184; In> [Precision(20);V(gamma());] CachedConstant: Info: constant gamma is being recalculated at precision 20 GammaConstNum: Info: used 56 iterations at working precision 24 Out> 0.57721566490153286061; |
N(GoldenRatio) GoldenRatio() |
The ancient Greeks defined the "golden ratio" as follows: If one divides a length 1 into two pieces x and 1-x, such that the ratio of 1 to x is the same as the ratio of x to 1-x, then 1/x<=>1.618... is the "golden ratio".
The constant is available symbolically as GoldenRatio or numerically as a function GoldenRatio(). This is a "cached constant" which is recalculated only when precision is increased. The numerical value of the constant can also be obtained as N(GoldenRatio).
In> x:=GoldenRatio - 1 Out> GoldenRatio-1; In> N(x) Out> 0.6180339887; In> N(1/GoldenRatio) Out> 0.6180339887; In> [Precision(20);V(GoldenRatio());] |
CachedConstant: Info: constant GoldenRatio is being recalculated at precision 20 Out> 1.6180339887498948482; |
N(Catalan) Catalan() |
The constant is available symbolically as Catalan or numerically as a function Catalan(). This is a "cached constant" which is recalculated only when precision is increased. The numerical value of the constant can also be obtained as N(Catalan). The low-level numerical computations are performed by the routine CatalanConstNum.
In> N(Catalan) Out> 0.9159655941; In> DirichletBeta(2) Out> Catalan; In> [Precision(20);V(Catalan());] |
CachedConstant: Info: constant Catalan is being recalculated at precision 20 Out> 0.91596559417721901505; |
OdeSolve(expr1==expr2) |
First and second derivatives are entered as y',y''. Higher order derivatives may be entered as y(n), where n is any integer.
In> OdeSolve( y'' + y == 0 ) Out> C42*Sin(x)+C43*Cos(x); In> OdeSolve( 2*y'' + 3*y' + 5*y == 0 ) Out> Exp(((-3)*x)/4)*(C78*Sin(Sqrt(31/16)*x)+C79*Cos(Sqrt(31/16)*x)); In> OdeSolve( y'' - 4*y == 0 ) Out> C132*Exp((-2)*x)+C136*Exp(2*x); In> OdeSolve( y'' +2*y' + y == 0 ) Out> (C183+C184*x)*Exp(-x); |
OdeTest(eqn,testsol) |
testsol -- test solution
In> OdeTest(y''+y,Sin(x)+Cos(x)) Out> 0; In> OdeTest(y''+2*y,Sin(x)+Cos(x)) Out> Sin(x)+Cos(x); |
OdeOrder(eqn) |
In> OdeOrder(y'' + 2*y' == 0) Out> 2; In> OdeOrder(Sin(x)*y(5) + 2*y' == 0) Out> 5; In> OdeOrder(2*y + Sin(y) == 0) Out> 0; |
LaplaceTransform(t,s,func) |
s -- independent variable that is being transformed into
f -- function
In> LaplaceTransform(t,s,2*t^5+ t^2/2 ) Out> 240/s^6+2/(2*s^3); In> LaplaceTransform(t,s,t*Sin(2*t)*Exp(-3*t) ) Out> (2*(s+3))/(2*(2*(((s+3)/2)^2+1))^2); In> LaplaceTransform(t,s, BesselJ(3,2*t) ) Out> (Sqrt((s/2)^2+1)-s/2)^3/(2*Sqrt((s/2)^2+1)); In> LaplaceTransform(t,s,Exp(t^2)); // not of exponential order Out> LaplaceTransform(t,s,Exp(t^2)); In> LaplaceTransform(p,q,Ln(p)) Out> -(gamma+Ln(q))/q; |
LeviCivita(list) |
In> LeviCivita({1,2,3}) Out> 1; In> LeviCivita({2,1,3}) Out> -1; In> LeviCivita({2,2,3}) Out> 0; |
Permutations(list) |
In> Permutations({a,b,c}) Out> {{a,b,c},{a,c,b},{c,a,b},{b,a,c}, {b,c,a},{c,b,a}}; |
Dot(t1,t2) t1 . t2 |
In> Dot({1,2},{3,4}) Out> 11; In> Dot({{1,2},{3,4}},{5,6}) Out> {17,39}; In> Dot({5,6},{{1,2},{3,4}}) Out> {23,34}; In> Dot({{1,2},{3,4}},{{5,6},{7,8}}) Out> {{19,22},{43,50}}; |
Or, using the "."-Operator: |
In> {1,2} . {3,4} Out> 11; In> {{1,2},{3,4}} . {5,6} Out> {17,39}; In> {5,6} . {{1,2},{3,4}} Out> {23,34}; In> {{1,2},{3,4}} . {{5,6},{7,8}} Out> {{19,22},{43,50}}; |
InProduct(a,b) |
This function is superceded by the . operator.
In> {a,b,c} . {d,e,f}; Out> a*d+b*e+c*f; |
CrossProduct(a,b) a X b |
In> {a,b,c} X {d,e,f}; Out> {b*f-c*e,c*d-a*f,a*e-b*d}; |
Outer(t1,t2) t1 o t2 |
In> Outer({1,2},{3,4,5}) Out> {{3,4,5},{6,8,10}}; In> Outer({a,b},{c,d}) Out> {{a*c,a*d},{b*c,b*d}}; |
Or, using the "o"-Operator: |
In> {1,2} o {3,4,5} Out> {{3,4,5},{6,8,10}}; In> {a,b} o {c,d} Out> {{a*c,a*d},{b*c,b*d}}; |
ZeroVector(n) |
In> ZeroVector(4) Out> {0,0,0,0}; |
BaseVector(k, n) |
n -- dimension of the vector
In> BaseVector(2,4) Out> {0,1,0,0}; |
Identity(n) |
In> Identity(3) Out> {{1,0,0},{0,1,0},{0,0,1}}; |
ZeroMatrix(n) ZeroMatrix(n, m) |
m -- number of columns
In> ZeroMatrix(3,4) Out> {{0,0,0,0},{0,0,0,0},{0,0,0,0}}; In> ZeroMatrix(3) Out> {{0,0,0},{0,0,0},{0,0,0}}; |
Diagonal(A) |
In> Diagonal(5*Identity(4)) Out> {5,5,5,5}; In> Diagonal(HilbertMatrix(3)) Out> {1,1/3,1/5}; |
DiagonalMatrix(d) |
In> DiagonalMatrix(1 .. 4) Out> {{1,0,0,0},{0,2,0,0},{0,0,3,0},{0,0,0,4}}; |
OrthogonalBasis(W) |
In> OrthogonalBasis({{1,1,0},{2,0,1},{2,2,1}}) Out> {{1,1,0},{1,-1,1},{-1/3,1/3,2/3}}; |
OrthonormalBasis(W) |
In> OrthonormalBasis({{1,1,0},{2,0,1},{2,2,1}}) Out> {{Sqrt(1/2),Sqrt(1/2),0},{Sqrt(1/3),-Sqrt(1/3),Sqrt(1/3)}, {-Sqrt(1/6),Sqrt(1/6),Sqrt(2/3)}}; |
IsScalar(expr) |
In> IsScalar(7) Out> True; In> IsScalar(Sin(x)+x) Out> True; In> IsScalar({x,y}) Out> False; |
IsVector(expr) |
IsVector(pred,expr) |
pred -- predicate test (e.g. IsNumber, IsInteger, ...)
In> IsVector({a,b,c}) Out> True; In> IsVector({a,{b},c}) Out> False; In> IsVector(IsInteger,{1,2,3}) Out> True; In> IsVector(IsInteger,{1,2.5,3}) Out> False; |
IsMatrix(expr) |
IsMatrix(pred,expr) |
pred -- predicate test (e.g. IsNumber, IsInteger, ...)
In> IsMatrix(1) Out> False; In> IsMatrix({1,2}) Out> False; In> IsMatrix({{1,2},{3,4}}) Out> True; In> IsMatrix(IsRational,{{1,2},{3,4}}) Out> False; In> IsMatrix(IsRational,{{1/2,2/3},{3/4,4/5}}) Out> True; |
IsSquareMatrix(expr) |
IsSquareMatrix(pred,expr) |
pred -- predicate test (e.g. IsNumber, IsInteger, ...)
In> IsSquareMatrix({{1,2},{3,4}}); Out> True; In> IsSquareMatrix({{1,2,3},{4,5,6}}); Out> False; In> IsSquareMatrix(IsBoolean,{{1,2},{3,4}}); Out> False; In> IsSquareMatrix(IsBoolean,{{True,False},{False,True}}); Out> True; |
Normalize(v) |
In> v:=Normalize({3,4}) Out> {3/5,4/5}; In> v . v Out> 1; |
Transpose(M) |
In> Transpose({{a,b}}) Out> {{a},{b}}; |
Determinant(M) |
In> A:=DiagonalMatrix(1 .. 4) Out> {{1,0,0,0},{0,2,0,0},{0,0,3,0},{0,0,0,4}}; In> Determinant(A) Out> 24; |
Trace(M) |
In> A:=DiagonalMatrix(1 .. 4) Out> {{1,0,0,0},{0,2,0,0},{0,0,3,0},{0,0,0,4}}; In> Trace(A) Out> 10; |
Inverse(M) |
In> A:=DiagonalMatrix({a,b,c}) Out> {{a,0,0},{0,b,0},{0,0,c}}; In> B:=Inverse(A) Out> {{(b*c)/(a*b*c),0,0},{0,(a*c)/(a*b*c),0}, {0,0,(a*b)/(a*b*c)}}; In> Simplify(B) Out> {{1/a,0,0},{0,1/b,0},{0,0,1/c}}; |
Minor(M,i,j) |
i, j - positive integers
In> A := {{1,2,3}, {4,5,6}, {7,8,9}}; Out> {{1,2,3},{4,5,6},{7,8,9}}; In> PrettyForm(A); / \ | ( 1 ) ( 2 ) ( 3 ) | | | | ( 4 ) ( 5 ) ( 6 ) | | | | ( 7 ) ( 8 ) ( 9 ) | \ / Out> True; In> Minor(A,1,2); Out> -6; In> Determinant({{2,3}, {8,9}}); Out> -6; |
CoFactor(M,i,j) |
i, j - positive integers
In> A := {{1,2,3}, {4,5,6}, {7,8,9}}; Out> {{1,2,3},{4,5,6},{7,8,9}}; In> PrettyForm(A); / \ | ( 1 ) ( 2 ) ( 3 ) | | | | ( 4 ) ( 5 ) ( 6 ) | | | | ( 7 ) ( 8 ) ( 9 ) | \ / Out> True; In> CoFactor(A,1,2); Out> 6; In> Minor(A,1,2); Out> -6; In> Minor(A,1,2) * (-1)^(1+2); Out> 6; |
MatrixPower(mat,n) |
n -- an integer
In> A:={{1,2},{3,4}} Out> {{1,2},{3,4}}; In> MatrixPower(A,0) Out> {{1,0},{0,1}}; In> MatrixPower(A,1) Out> {{1,2},{3,4}}; In> MatrixPower(A,3) Out> {{37,54},{81,118}}; In> MatrixPower(A,-3) Out> {{-59/4,27/4},{81/8,-37/8}}; |
SolveMatrix(M,v) |
v -- a vector
In> A := {{1,2}, {3,4}}; Out> {{1,2},{3,4}}; In> v := {5,6}; Out> {5,6}; In> x := SolveMatrix(A, v); Out> {-4,9/2}; In> A * x; Out> {5,6}; |
CharacteristicEquation(matrix,var) |
var -- a free variable
In> A:=DiagonalMatrix({a,b,c}) Out> {{a,0,0},{0,b,0},{0,0,c}}; In> B:=CharacteristicEquation(A,x) Out> (a-x)*(b-x)*(c-x); In> Expand(B,x) Out> (b+a+c)*x^2-x^3-((b+a)*c+a*b)*x+a*b*c; |
EigenValues(matrix) |
It first determines the characteristic equation, and then factorizes this equation, returning the roots of the characteristic equation Det(matrix-x*identity).
In> M:={{1,2},{2,1}} Out> {{1,2},{2,1}}; In> EigenValues(M) Out> {3,-1}; |
EigenVectors(A,eigenvalues) |
eigenvalues -- list of eigenvalues as returned by EigenValues
In> M:={{1,2},{2,1}} Out> {{1,2},{2,1}}; In> e:=EigenValues(M) Out> {3,-1}; In> EigenVectors(M,e) Out> {{-ki2/ -1,ki2},{-ki2,ki2}}; |
IsHermitian(A) |
In> IsHermitian({{0,I},{-I,0}}) Out> True; In> IsHermitian({{0,I},{2,0}}) Out> False; |
IsOrthogonal(A) |
In> A := {{1,2,2},{2,1,-2},{-2,2,-1}}; Out> {{1,2,2},{2,1,-2},{-2,2,-1}}; In> PrettyForm(A/3) |
/ \ | / 1 \ / 2 \ / 2 \ | | | - | | - | | - | | | \ 3 / \ 3 / \ 3 / | | | | / 2 \ / 1 \ / -2 \ | | | - | | - | | -- | | | \ 3 / \ 3 / \ 3 / | | | | / -2 \ / 2 \ / -1 \ | | | -- | | - | | -- | | | \ 3 / \ 3 / \ 3 / | \ / Out> True; In> IsOrthogonal(A/3) Out> True; |
IsDiagonal(A) |
In> IsDiagonal(Identity(5)) Out> True; In> IsDiagonal(HilbertMatrix(5)) Out> False; |
IsLowerTriangular(A) IsUpperTriangular(A) |
IsLowerTriangular(A) returns True if A is a lower triangular matrix and False otherwise. IsUpperTriangular(A) returns True if A is an upper triangular matrix and False otherwise.
In> IsUpperTriangular(Identity(5)) Out> True; In> IsLowerTriangular(Identity(5)) Out> True; In> IsLowerTriangular({{1,2},{0,1}}) Out> False; In> IsUpperTriangular({{1,2},{0,1}}) Out> True; |
In> IsUpperTriangular({{1,2,3},{0,1,2}}) Out> False; |
IsSymmetric(A) |
In> A := {{1,0,0,0,1},{0,2,0,0,0},{0,0,3,0,0}, {0,0,0,4,0},{1,0,0,0,5}}; In> PrettyForm(A) |
/ \ | ( 1 ) ( 0 ) ( 0 ) ( 0 ) ( 1 ) | | | | ( 0 ) ( 2 ) ( 0 ) ( 0 ) ( 0 ) | | | | ( 0 ) ( 0 ) ( 3 ) ( 0 ) ( 0 ) | | | | ( 0 ) ( 0 ) ( 0 ) ( 4 ) ( 0 ) | | | | ( 1 ) ( 0 ) ( 0 ) ( 0 ) ( 5 ) | \ / Out> True; In> IsSymmetric(A) Out> True; |
IsSkewSymmetric(A) |
In> A := {{0,-1},{1,0}} Out> {{0,-1},{1,0}}; In> PrettyForm(%) |
/ \ | ( 0 ) ( -1 ) | | | | ( 1 ) ( 0 ) | \ / Out> True; In> IsSkewSymmetric(A); Out> True; |
IsUnitary(A) |
A matrix A is orthogonal iff A^(-1) = Transpose( Conjugate(A) ). This is equivalent to the fact that the columns of A build an orthonormal system (with respect to the scalar product defined by InProduct).
In> IsUnitary({{0,I},{-I,0}}) Out> True; In> IsUnitary({{0,I},{2,0}}) Out> False; |
IsIdempotent(A) |
In> IsIdempotent(ZeroMatrix(10,10)); Out> True; In> IsIdempotent(Identity(20)) Out> True; |
JacobianMatrix(functions,variables) |
variables -- an n-dimensional vector of variables
The ( i, j)-th element of the Jacobian matrix is defined as the derivative of i-th function with respect to the j-th variable.
In> JacobianMatrix( {Sin(x),Cos(y)}, {x,y} ); Out> {{Cos(x),0},{0,-Sin(y)}}; In> PrettyForm(%) |
/ \ | ( Cos( x ) ) ( 0 ) | | | | ( 0 ) ( -( Sin( y ) ) ) | \ / |
VandermondeMatrix(vector) |
The ( i, j)-th element of the Vandermonde matrix is defined as i^(j-1).
In> VandermondeMatrix({1,2,3,4}) Out> {{1,1,1,1},{1,2,3,4},{1,4,9,16},{1,8,27,64}}; In>PrettyForm(%) |
/ \ | ( 1 ) ( 1 ) ( 1 ) ( 1 ) | | | | ( 1 ) ( 2 ) ( 3 ) ( 4 ) | | | | ( 1 ) ( 4 ) ( 9 ) ( 16 ) | | | | ( 1 ) ( 8 ) ( 27 ) ( 64 ) | \ / |
HessianMatrix(function,var) |
var -- an n-dimensional vector of variables
If f(x) is a function of an n-dimensional vector x, then the ( i, j)-th element of the Hessian matrix of the function f(x) is defined as Deriv(x[i])Deriv(x[j])f(x). If the third order mixed partials are continuous, then the Hessian matrix is symmetric (a standard theorem of calculus).
The Hessian matrix is used in the second derivative test to discern if a critical point is a local maximum, a local minimum or a saddle point.
In> HessianMatrix(3*x^2-2*x*y+y^2-8*y, {x,y} ) Out> {{6,-2},{-2,2}}; In> PrettyForm(%) |
/ \ | ( 6 ) ( -2 ) | | | | ( -2 ) ( 2 ) | \ / |
Sparsity(matrix) |
In> Sparsity(Identity(2)) Out> 0.5; In> Sparsity(Identity(10)) Out> 0.9; In> Sparsity(HankelMatrix(10)) Out> 0.45; In> Sparsity(HankelMatrix(100)) Out> 0.495; In> Sparsity(HilbertMatrix(10)) Out> 0; In> Sparsity(ZeroMatrix(10,10)) Out> 1; |
HilbertMatrix(n) HilbertMatrix(n,m) |
In> PrettyForm(HilbertMatrix(4)) |
/ \ | ( 1 ) / 1 \ / 1 \ / 1 \ | | | - | | - | | - | | | \ 2 / \ 3 / \ 4 / | | | | / 1 \ / 1 \ / 1 \ / 1 \ | | | - | | - | | - | | - | | | \ 2 / \ 3 / \ 4 / \ 5 / | | | | / 1 \ / 1 \ / 1 \ / 1 \ | | | - | | - | | - | | - | | | \ 3 / \ 4 / \ 5 / \ 6 / | | | | / 1 \ / 1 \ / 1 \ / 1 \ | | | - | | - | | - | | - | | | \ 4 / \ 5 / \ 6 / \ 7 / | \ / |
HilbertInverseMatrix(n) |
In> PrettyForm(HilbertInverseMatrix(4)) |
/ \ | ( 16 ) ( -120 ) ( 240 ) ( -140 ) | | | | ( -120 ) ( 1200 ) ( -2700 ) ( 1680 ) | | | | ( 240 ) ( -2700 ) ( 6480 ) ( -4200 ) | | | | ( -140 ) ( 1680 ) ( -4200 ) ( 2800 ) | \ / |
ToeplitzMatrix(N) |
In> PrettyForm(ToeplitzMatrix({1,2,3,4,5})) |
/ \ | ( 1 ) ( 2 ) ( 3 ) ( 4 ) ( 5 ) | | | | ( 2 ) ( 1 ) ( 2 ) ( 3 ) ( 4 ) | | | | ( 3 ) ( 2 ) ( 1 ) ( 2 ) ( 3 ) | | | | ( 4 ) ( 3 ) ( 2 ) ( 1 ) ( 2 ) | | | | ( 5 ) ( 4 ) ( 3 ) ( 2 ) ( 1 ) | \ / |
WronskianMatrix(func,var) |
var -- a variable to differentiate with respect to
The Wronskian matrix is created by putting each function as the first element of each column, and filling in the rest of each column by the ( i-1)-th derivative, where i is the current row.
The Wronskian matrix is used to verify that the n functions are linearly independent, usually solutions to a differential equation. If the determinant of the Wronskian matrix is zero, then the functions are dependent, otherwise they are independent.
In> WronskianMatrix({Sin(x),Cos(x),x^4},x); Out> {{Sin(x),Cos(x),x^4},{Cos(x),-Sin(x),4*x^3}, {-Sin(x),-Cos(x),12*x^2}}; In> PrettyForm(%) |
/ \ | ( Sin( x ) ) ( Cos( x ) ) / 4 \ | | \ x / | | | | ( Cos( x ) ) ( -( Sin( x ) ) ) / 3 \ | | \ 4 * x / | | | | ( -( Sin( x ) ) ) ( -( Cos( x ) ) ) / 2 \ | | \ 12 * x / | \ / |
In> A:=Determinant( WronskianMatrix( {x^4,x^3,2*x^4 + 3*x^3},x ) ) Out> x^4*3*x^2*(24*x^2+18*x)-x^4*(8*x^3+9*x^2)*6*x +(2*x^4+3*x^3)*4*x^3*6*x-4*x^6*(24*x^2+18*x)+x^3 *(8*x^3+9*x^2)*12*x^2-(2*x^4+3*x^3)*3*x^2*12*x^2; In> Simplify(A) Out> 0; |
SylvesterMatrix(poly1,poly2,variable) |
poly2 -- polynomial
variable -- variable to express the matrix for
The Sylvester matrix is closely related to the resultant, which is defined as the determinant of the Sylvester matrix. Two polynomials share common roots only if the resultant is zero.
In> ex1:= x^2+2*x-a Out> x^2+2*x-a; In> ex2:= x^2+a*x-4 Out> x^2+a*x-4; In> A:=SylvesterMatrix(ex1,ex2,x) Out> {{1,2,-a,0},{0,1,2,-a}, {1,a,-4,0},{0,1,a,-4}}; In> B:=Determinant(A) Out> 16-a^2*a- -8*a-4*a+a^2- -2*a^2-16-4*a; In> Simplify(B) Out> 3*a^2-a^3; |
The above example shows that the two polynomials have common zeros if a=3.
MatrixSolve(A,b) |
b -- row vector
In> A:={{2,4,-2,-2},{1,2,4,-3},{-3,-3,8,-2},{-1,1,6,-3}}; Out> {{2,4,-2,-2},{1,2,4,-3},{-3,-3,8,-2},{-1,1,6,-3}}; In> b:={-4,5,7,7}; Out> {-4,5,7,7}; In> MatrixSolve(A,b); Out> {1,2,3,4}; |
Cholesky(A) |
In> A:={{4,-2,4,2},{-2,10,-2,-7},{4,-2,8,4},{2,-7,4,7}} Out> {{4,-2,4,2},{-2,10,-2,-7},{4,-2,8,4},{2,-7,4,7}}; In> R:=Cholesky(A); Out> {{2,-1,2,1},{0,3,0,-2},{0,0,2,1},{0,0,0,1}}; In> Transpose(R)*R = A Out> True; In> Cholesky(4*Identity(5)) Out> {{2,0,0,0,0},{0,2,0,0,0},{0,0,2,0,0},{0,0,0,2,0},{0,0,0,0,2}}; In> Cholesky(HilbertMatrix(3)) Out> {{1,1/2,1/3},{0,Sqrt(1/12),Sqrt(1/12)},{0,0,Sqrt(1/180)}}; In> Cholesky(ToeplitzMatrix({1,2,3})) In function "Check" : CommandLine(1) : "Cholesky: Matrix is not positive definite" |
RandomIntegerMatrix(rows,cols,from,to) |
cols -- number of cols in matrix
from -- lower bound
to -- upper bound
In> PrettyForm( RandomIntegerMatrix(5,5,-2^10,2^10) ) |
/ \ | ( -506 ) ( 749 ) ( -574 ) ( -674 ) ( -106 ) | | | | ( 301 ) ( 151 ) ( -326 ) ( -56 ) ( -277 ) | | | | ( 777 ) ( -761 ) ( -161 ) ( -918 ) ( -417 ) | | | | ( -518 ) ( 127 ) ( 136 ) ( 797 ) ( -406 ) | | | | ( 679 ) ( 854 ) ( -78 ) ( 503 ) ( 772 ) | \ / |
Expand(expr) Expand(expr, var) Expand(expr, varlist) |
var -- a variable
varlist -- a list of variables
If the polynomial "expr" contains only one variable, the first calling sequence can be used. Otherwise, the second form should be used which explicitly mentions that "expr" should be considered as a polynomial in the variable "var". The third calling form can be used for multivariate polynomials. Firstly, the polynomial "expr" is expanded with respect to the first variable in "varlist". Then the coefficients are all expanded with respect to the second variable, and so on.
In> PrettyPrinter("PrettyForm"); True |
In> Expand((1+x)^5); 5 4 3 2 x + 5 * x + 10 * x + 10 * x + 5 * x + 1 |
In> Expand((1+x-y)^2, x); 2 2 x + 2 * ( 1 - y ) * x + ( 1 - y ) |
In> Expand((1+x-y)^2, {x,y}); 2 2 x + ( -2 * y + 2 ) * x + y - 2 * y + 1 |
Degree(expr) Degree(expr, var) |
var -- a variable occurring in "expr"
In> Degree(x^5+x-1); Out> 5; In> Degree(a+b*x^3, a); Out> 1; In> Degree(a+b*x^3, x); Out> 3; |
Coef(expr, var, order) |
var -- a variable occurring in "expr"
order -- integer or list of integers
In> e := Expand((a+x)^4,x) Out> x^4+4*a*x^3+(a^2+(2*a)^2+a^2)*x^2+ (a^2*2*a+2*a^3)*x+a^4; In> Coef(e,a,2) Out> 6*x^2; In> Coef(e,a,0 .. 4) Out> {x^4,4*x^3,6*x^2,4*x,1}; |
Content(expr) |
In> poly := 2*x^2 + 4*x; Out> 2*x^2+4*x; In> c := Content(poly); Out> 2*x; In> pp := PrimitivePart(poly); Out> x+2; In> Expand(pp*c); Out> 2*x^2+4*x; |
PrimitivePart(expr) |
In> poly := 2*x^2 + 4*x; Out> 2*x^2+4*x; In> c := Content(poly); Out> 2*x; In> pp := PrimitivePart(poly); Out> x+2; In> Expand(pp*c); Out> 2*x^2+4*x; |
LeadingCoef(poly) LeadingCoef(poly, var) |
var -- a variable
In> poly := 2*x^2 + 4*x; Out> 2*x^2+4*x; In> lc := LeadingCoef(poly); Out> 2; In> m := Monic(poly); Out> x^2+2*x; In> Expand(lc*m); Out> 2*x^2+4*x; In> LeadingCoef(2*a^2 + 3*a*b^2 + 5, a); Out> 2; In> LeadingCoef(2*a^2 + 3*a*b^2 + 5, b); Out> 3*a; |
Monic(poly) Monic(poly, var) |
var -- a variable
In> poly := 2*x^2 + 4*x; Out> 2*x^2+4*x; In> lc := LeadingCoef(poly); Out> 2; In> m := Monic(poly); Out> x^2+2*x; In> Expand(lc*m); Out> 2*x^2+4*x; In> Monic(2*a^2 + 3*a*b^2 + 5, a); Out> a^2+(a*3*b^2)/2+5/2; In> Monic(2*a^2 + 3*a*b^2 + 5, b); Out> b^2+(2*a^2+5)/(3*a); |
RandomPoly(var,deg,coefmin,coefmax) |
deg -- degree of resulting univariate polynomial
coefmin -- minimum value for coefficients
coefmax -- maximum value for coefficients
In> RandomPoly(x,3,-10,10) Out> 3*x^3+10*x^2-4*x-6; In> RandomPoly(x,3,-10,10) Out> -2*x^3-8*x^2+8; |
Horner(expr, var) |
var -- a variable
If one converts this polynomial into Horner form, one gets the equivalent expression
Both expression are equal, but the latter form gives a more efficient way to evaluate the polynomial as the powers have disappeared.
In> expr1:=Expand((1+x)^4) Out> x^4+4*x^3+6*x^2+4*x+1; In> Horner(expr1,x) Out> (((x+4)*x+6)*x+4)*x+1; |
ExpandBrackets(expr) |
In> Expand((a-x)*(b-x),x) Out> x^2-(b+a)*x+a*b; In> Expand((a-x)*(b-x),{x,a,b}) Out> x^2-(b+a)*x+b*a; In> ExpandBrackets((a-x)*(b-x)) Out> a*b-x*b+x^2-a*x; |
EvaluateHornerScheme(coeffs,x) |
x -- expression
In> EvaluateHornerScheme({a,b,c,d},x) Out> a+x*(b+x*(c+x*d)); |
OrthoP(n, x); OrthoP(n, a, b, x); |
x -- point to evaluate polynomial at
a, b -- parameters for Jacobi polynomial
The Jacobi polynomials are orthogonal with respect to the weight function (1-x)^a*(1+x)^b on the interval [-1,1]. They satisfy the recurrence relation
Legendre polynomials are a special case of Jacobi polynomials with the specific parameter values a=b=0. So they form an orthogonal system with respect to the weight function identically equal to 1 on the interval [-1,1], and they satisfy the recurrence relation
Most of the work is performed by the internal function OrthoPoly.
In> PrettyPrinter("PrettyForm"); True In> OrthoP(3, x); / 2 \ | 5 * x 3 | x * | ------ - - | \ 2 2 / In> OrthoP(3, 1, 2, x); 1 / / 21 * x 7 \ 7 \ - + x * | x * | ------ - - | - - | 2 \ \ 2 2 / 2 / In> Expand(%) 3 2 21 * x - 7 * x - 7 * x + 1 ---------------------------- 2 In> OrthoP(3, 1, 2, 0.5); -0.8124999999 |
OrthoH(n, x); |
x -- point to evaluate polynomial at
The Hermite polynomials are orthogonal with respect to the weight function Exp(-x^2/2) on the entire real axis. They satisfy the recurrence relation
Most of the work is performed by the internal function OrthoPoly.
In> OrthoH(3, x); Out> x*(8*x^2-12); In> OrthoH(6, 0.5); Out> 31; |
OrthoG(n, a, x); |
a -- parameter
x -- point to evaluate polynomial at
The Gegenbauer polynomials are orthogonal with respect to the weight function (1-x^2)^(a-1/2) on the interval [-1,1]. Hence they are connected to the Jacobi polynomials via
Most of the work is performed by the internal function OrthoPoly.
In> OrthoG(5, 1, x); Out> x*((32*x^2-32)*x^2+6); In> OrthoG(5, 2, -0.5); Out> 2; |
OrthoL(n, a, x); |
a -- parameter
x -- point to evaluate polynomial at
The Laguerre polynomials are orthogonal with respect to the weight function x^a*Exp(-x) on the positive real axis. They satisfy the recurrence relation
Most of the work is performed by the internal function OrthoPoly.
In> OrthoL(3, 1, x); Out> x*(x*(2-x/6)-6)+4; In> OrthoL(3, 1/2, 0.25); Out> 1.2005208334; |
OrthoT(n, x); OrthoU(n, x); |
x -- point to evaluate polynomial at
The Chebyshev polynomials are orthogonal with respect to the weight function (1-x^2)^(-1/2). Hence they are a special case of the Gegenbauer polynomials G(n,a,x), with a=0. They satisfy the recurrence relations
In> OrthoT(3, x); Out> 2*x*(2*x^2-1)-x; In> OrthoT(10, 0.9); Out> -0.2007474688; In> OrthoU(3, x); Out> 4*x*(2*x^2-1); In> OrthoU(10, 0.9); Out> -2.2234571776; |
OrthoPSum(c, x); OrthoPSum(c, a, b, x); OrthoHSum(c, x); OrthoLSum(c, a, x); OrthoGSum(c, a, x); OrthoTSum(c, x); OrthoUSum(c, x); |
a, b -- parameters of specific polynomials
x -- point to evaluate polynomial at
The list of coefficients starts with the lowest order, so that for example OrthoLSum(c, a, x) = c[1] L[0](a,x) + c[2] L[1](a,x) + ... + c[N] L[N-1](a,x).
See pages for specific orthogonal polynomials for more details on the parameters of the polynomials.
Most of the work is performed by the internal function OrthoPolySum. The individual polynomials entering the series are not computed, only the sum of the series.
In> Expand(OrthoPSum({1,0,0,1/7,1/8}, 3/2, \ 2/3, x)); Out> (7068985*x^4)/3981312+(1648577*x^3)/995328+ (-3502049*x^2)/4644864+(-4372969*x)/6967296 +28292143/27869184; |
OrthoPoly(name, n, par, x) |
n -- degree of the polynomial
par -- list of values for the parameters
x -- point to evaluate at
All known families are stored in the association list KnownOrthoPoly. The name serves as key. At the moment the following names are known to Yacas: "Jacobi", "Gegenbauer", "Laguerre", "Hermite", "Tscheb1", and "Tscheb2". The value associated to the key is a pure function that takes two arguments: the order n and the extra parameters p, and returns a list of two lists: the first list contains the coefficients A,B of the n=1 polynomial, i.e. A+B*x; the second list contains the coefficients A,B,C in the recurrence relation, i.e. P[n]=(A+B*x)*P[n-1]+C*P[n-2]. (There are only 3 coefficients in the second list, because none of the polynomials use C+D*x instead of C in the recurrence relation. This is assumed in the implementation!)
If the argument x is numerical, the function OrthoPolyNumeric is called. Otherwise, the function OrthoPolyCoeffs computes a list of coefficients, and EvaluateHornerScheme converts this list into a polynomial expression.
OrthoPolySum(name, c, par, x) |
c -- list of coefficients
par -- list of values for the parameters
x -- point to evaluate at
The algorithm used to compute the series without first computing the individual polynomials is the Clenshaw-Smith recurrence scheme. (See the algorithms book for explanations.)
If the argument x is numerical, the function OrthoPolySumNumeric is called. Otherwise, the function OrthoPolySumCoeffs computes the list of coefficients of the resulting polynomial, and EvaluateHornerScheme converts this list into a polynomial expression.
SquareFree(p) |
In> Expand((x+1)^5) Out> x^5+5*x^4+10*x^3+10*x^2+5*x+1; In> SquareFree(%) Out> (x+1)/5; In> Monic(%) Out> x+1; |
FindRealRoots(p) |
In> p:=Expand((x+3.1)^5*(x-6.23)) Out> x^6+9.27*x^5-0.465*x^4-300.793*x^3- 1394.2188*x^2-2590.476405*x-1783.5961073; In> FindRealRoots(p) Out> {-3.1,6.23}; |
NumRealRoots(p) |
In> NumRealRoots(x^2-1) Out> 2; In> NumRealRoots(x^2+1) Out> 0; |
MinimumBound(p) MaximumBound(p) |
In> p:=SquareFree(Rationalize((x-3.1)*(x+6.23))) Out> (-40000*x^2-125200*x+772520)/870489; In> MinimumBound(p) Out> 5000000000/2275491039; In> N(%) Out> 2.1973279236; In> MaximumBound(p) Out> 10986639613/1250000000; In> N(%) Out> 8.7893116904; |
Head(list) |
In> Head({a,b,c}) Out> a; In> Head(f(a,b,c)); Out> a; |
Tail(list) |
In> Tail({a,b,c}) Out> {b,c}; |
Length(object) |
In> Length({a,b,c}) Out> 3; In> Length("abcdef"); Out> 6; |
Map(fn, list) |
list -- list of lists of arguments
In> MapSingle("Sin",{a,b,c}); Out> {Sin(a),Sin(b),Sin(c)}; In> Map("+",{{a,b},{c,d}}); Out> {a+c,b+d}; |
MapSingle(fn, list) |
list -- list of arguments
The /@ operator provides a shorthand for MapSingle.
In> MapSingle("Sin",{a,b,c}); Out> {Sin(a),Sin(b),Sin(c)}; In> MapSingle({{x},x^2}, {a,2,c}); Out> {a^2,4,c^2}; |
RandomIntegerVector(nr, from, to) |
from -- lower bound
to -- upper bound
In> RandomIntegerVector(4,-3,3) Out> {0,3,2,-2}; |
MakeVector(var,n) |
n -- length of the vector
In> MakeVector(a,3) Out> {a1,a2,a3}; |
Select(pred, list) |
list -- a list of elements to select from
In> Select("IsInteger",{a,b,2,c,3,d,4,e,f}) Out> {2,3,4}; |
Nth(list, n) |
n -- index of entry to pick
More generally, Nth returns the n-th operand of the expression passed as first argument.
An alternative but equivalent form of Nth(list, n) is list[n].
In> lst := {a,b,c,13,19}; Out> {a,b,c,13,19}; In> Nth(lst, 3); Out> c; In> lst[3]; Out> c; In> Nth(lst, {3,4,1}); Out> {c,13,a}; In> Nth(b*(a+c), 2); Out> a+c; |
DestructiveReverse(list) |
Destructive commands are faster than their nondestructive counterparts. Reverse is the non-destructive version of this function.
In> lst := {a,b,c,13,19}; Out> {a,b,c,13,19}; In> revlst := DestructiveReverse(lst); Out> {19,13,c,b,a}; In> lst; Out> {a}; |
Reverse(list) |
In> lst:={a,b,c,13,19} Out> {a,b,c,13,19}; In> revlst:=Reverse(lst) Out> {19,13,c,b,a}; In> lst Out> {a,b,c,13,19}; |
List(expr1, expr2, ...) |
In> List(); Out> {}; In> List(a,b); Out> {a,b}; In> List(a,{1,2},d); Out> {a,{1,2},d}; |
UnList(list) |
Note that "list" is evaluated before the function application is formed, but the resulting expression is left unevaluated. The functions UnList() and Hold() both stop the process of evaluation.
In> UnList({Cos, x}); Out> Cos(x); In> UnList({f}); Out> f(); In> UnList({Taylor,x,0,5,Cos(x)}); Out> Taylor(x,0,5)Cos(x); In> Eval(%); Out> 1-x^2/2+x^4/24; |
Listify(expr) |
In> Listify(Cos(x)); Out> {Cos,x}; In> Listify(3*a); Out> {*,3,a}; |
Concat(list1, list2, ...) |
In> Concat({a,b}, {c,d}); Out> {a,b,c,d}; In> Concat({5}, {a,b,c}, {{f(x)}}); Out> {5,a,b,c,{f(x)}}; |
Delete(list, n) |
n -- index of the element to remove
In> Delete({a,b,c,d,e,f}, 4); Out> {a,b,c,e,f}; |
Insert(list, n, expr) |
n -- index at which to insert
expr -- expression to insert in "list"
In> Insert({a,b,c,d}, 4, x); Out> {a,b,c,x,d}; In> Insert({a,b,c,d}, 5, x); Out> {a,b,c,d,x}; In> Insert({a,b,c,d}, 1, x); Out> {x,a,b,c,d}; |
DestructiveDelete(list, n) |
n -- index of the element to remove
Destructive commands run faster than their nondestructive counterparts because the latter copy the list before they alter it.
In> lst := {a,b,c,d,e,f}; Out> {a,b,c,d,e,f}; In> Delete(lst, 4); Out> {a,b,c,e,f}; In> lst; Out> {a,b,c,d,e,f}; In> DestructiveDelete(lst, 4); Out> {a,b,c,e,f}; In> lst; Out> {a,b,c,e,f}; |
DestructiveInsert(list, n, expr) |
n -- index at which to insert
expr -- expression to insert in "list"
Destructive commands run faster than their nondestructive counterparts because the latter copy the list before they alter it.
In> lst := {a,b,c,d}; Out> {a,b,c,d}; In> Insert(lst, 2, x); Out> {a,x,b,c,d}; In> lst; Out> {a,b,c,d}; In> DestructiveInsert(lst, 2, x); Out> {a,x,b,c,d}; In> lst; Out> {a,x,b,c,d}; |
Replace(list, n, expr) |
n -- index of entry to replace
expr -- expression to replace the n-th entry with
In> Replace({a,b,c,d,e,f}, 4, x); Out> {a,b,c,x,e,f}; |
DestructiveReplace(list, n, expr) |
n -- index of entry to replace
expr -- expression to replace the n-th entry with
Destructive commands run faster than their nondestructive counterparts because the latter copy the list before they alter it.
In> lst := {a,b,c,d,e,f}; Out> {a,b,c,d,e,f}; In> Replace(lst, 4, x); Out> {a,b,c,x,e,f}; In> lst; Out> {a,b,c,d,e,f}; In> DestructiveReplace(lst, 4, x); Out> {a,b,c,x,e,f}; In> lst; Out> {a,b,c,x,e,f}; |
FlatCopy(list) |
In> reverse(l_IsList) <-- DestructiveReverse \ (FlatCopy(l)); Out> True; In> lst := {a,b,c,d,e}; Out> {a,b,c,d,e}; In> reverse(lst); Out> {e,d,c,b,a}; In> lst; Out> {a,b,c,d,e}; |
Contains(list, expr) |
expr -- expression to look for in "list"
In> Contains({a,b,c,d}, b); Out> True; In> Contains({a,b,c,d}, x); Out> False; In> Contains({a,{1,2,3},z}, 1); Out> False; In> Contains(a*b, b); Out> True; |
Find(list, expr) |
expr -- expression to look for in "list"
In> Find({a,b,c,d,e,f}, d); Out> 4; In> Find({1,2,3,2,1}, 2); Out> 2; In> Find({1,2,3,2,1}, 4); Out> -1; |
Append(list, expr) |
expr -- expression to append to the list
Note that due to the underlying data structure, the time it takes to append an entry at the end of a list grows linearly with the length of the list, while the time for prepending an entry at the beginning is constant.
In> Append({a,b,c,d}, 1); Out> {a,b,c,d,1}; |
DestructiveAppend(list, expr) |
expr -- expression to append to the list
Destructive commands run faster than their nondestructive counterparts because the latter copy the list before they alter it.
In> lst := {a,b,c,d}; Out> {a,b,c,d}; In> Append(lst, 1); Out> {a,b,c,d,1}; In> lst Out> {a,b,c,d}; In> DestructiveAppend(lst, 1); Out> {a,b,c,d,1}; In> lst; Out> {a,b,c,d,1}; |
RemoveDuplicates(list) |
In> RemoveDuplicates({1,2,3,2,1}); Out> {1,2,3}; In> RemoveDuplicates({a,1,b,1,c,1}); Out> {a,1,b,c}; |
Push(stack, expr) |
expr -- expression to push on "stack"
In> stack := {}; Out> {}; In> Push(stack, x); Out> {x}; In> Push(stack, x2); Out> {x2,x}; In> PopFront(stack); Out> x2; |
Pop(stack, n) |
n -- index of the element to remove
In> stack := {}; Out> {}; In> Push(stack, x); Out> {x}; In> Push(stack, x2); Out> {x2,x}; In> Push(stack, x3); Out> {x3,x2,x}; In> Pop(stack, 2); Out> x2; In> stack; Out> {x3,x}; |
PopFront(stack) |
In> stack := {}; Out> {}; In> Push(stack, x); Out> {x}; In> Push(stack, x2); Out> {x2,x}; In> Push(stack, x3); Out> {x3,x2,x}; In> PopFront(stack); Out> x3; In> stack; Out> {x2,x}; |
PopBack(stack) |
In> stack := {}; Out> {}; In> Push(stack, x); Out> {x}; In> Push(stack, x2); Out> {x2,x}; In> Push(stack, x3); Out> {x3,x2,x}; In> PopBack(stack); Out> x; In> stack; Out> {x3,x2}; |
Swap(list, i1, i2) |
i1, i2 -- indices of the entries in "list" to swap
Swap() works also on generic arrays.
In> lst := {a,b,c,d,e,f}; Out> {a,b,c,d,e,f}; In> Swap(lst, 2, 4); Out> {a,d,c,b,e,f}; |
Count(list, expr) |
expr -- expression to look for in "list"
In> lst := {a,b,c,b,a}; Out> {a,b,c,b,a}; In> Count(lst, a); Out> 2; In> Count(lst, c); Out> 1; In> Count(lst, x); Out> 0; |
Intersection(l1, l2) |
In> Intersection({a,b,c}, {b,c,d}); Out> {b,c}; In> Intersection({a,e,i,o,u}, {f,o,u,r,t,e,e,n}); Out> {e,o,u}; In> Intersection({1,2,2,3,3,3}, {1,1,2,2,3,3}); Out> {1,2,2,3,3}; |
Union(l1, l2) |
In> Union({a,b,c}, {b,c,d}); Out> {a,b,c,d}; In> Union({a,e,i,o,u}, {f,o,u,r,t,e,e,n}); Out> {a,e,i,o,u,f,r,t,n}; In> Union({1,2,2,3,3,3}, {2,2,3,3,4,4}); Out> {1,2,3,4}; |
Difference(l1, l2) |
In> Difference({a,b,c}, {b,c,d}); Out> {a}; In> Difference({a,e,i,o,u}, {f,o,u,r,t,e,e,n}); Out> {a,i}; In> Difference({1,2,2,3,3,3}, {2,2,3,4,4}); Out> {1,3,3}; |
FillList(expr, n) |
n -- the length of the list to construct
In> FillList(x, 5); Out> {x,x,x,x,x}; |
Drop(list, n) Drop(list, -n) Drop(list, {m,n}) |
n, m -- positive integers describing the entries to drop
In> lst := {a,b,c,d,e,f,g}; Out> {a,b,c,d,e,f,g}; In> Drop(lst, 2); Out> {c,d,e,f,g}; In> Drop(lst, -3); Out> {a,b,c,d}; In> Drop(lst, {2,4}); Out> {a,e,f,g}; |
Take(list, n) Take(list, -n) Take(list, {m,n}) |
n, m -- positive integers describing the entries to take
In> lst := {a,b,c,d,e,f,g}; Out> {a,b,c,d,e,f,g}; In> Take(lst, 2); Out> {a,b}; In> Take(lst, -3); Out> {e,f,g}; In> Take(lst, {2,4}); Out> {b,c,d}; |
Partition(list, n) |
n -- length of partitions
In> Partition({a,b,c,d,e,f,}, 2); Out> {{a,b},{c,d},{e,f}}; In> Partition(1 .. 11, 3); Out> {{1,2,3},{4,5,6},{7,8,9}}; |
Assoc(key, alist) |
alist -- association list to examine
Association lists are represented as a list of two-entry lists. The first element in the two-entry list is the key, the second element is the value stored under this key.
The call Assoc(key, alist) can (probably more intuitively) be accessed as alist[key].
In> writer := {}; Out> {}; In> writer["Iliad"] := "Homer"; Out> True; In> writer["Henry IV"] := "Shakespeare"; Out> True; In> writer["Ulysses"] := "James Joyce"; Out> True; In> Assoc("Henry IV", writer); Out> {"Henry IV","Shakespeare"}; In> Assoc("War and Peace", writer); Out> Empty; |
AssocIndices(alist) |
In> writer := {}; Out> {}; In> writer["Iliad"] := "Homer"; Out> True; In> writer["Henry IV"] := "Shakespeare"; Out> True; In> writer["Ulysses"] := "James Joyce"; Out> True; In> AssocIndices(writer); Out> {"Iliad","Henry IV","Ulysses"}; |
AssocDelete(alist, "key") AssocDelete(alist, {key, value}) |
"key" -- string, association key
value -- value of the key to be deleted
The second, longer form of the function deletes the entry that has both the specified key and the specified value. It can be used for two purposes:
At most one entry is deleted.
In> writer := {}; Out> {}; In> writer["Iliad"] := "Homer"; Out> True; In> writer["Henry IV"] := "Shakespeare"; Out> True; In> writer["Ulysses"] := "James Joyce"; Out> True; In> AssocDelete(writer, "Henry IV") Out> True; In> AssocDelete(writer, "Henry XII") Out> False; In> writer Out> {{"Ulysses","James Joyce"}, {"Iliad","Homer"}}; In> DestructiveAppend(writer, {"Ulysses", "Dublin"}); Out> {{"Iliad","Homer"},{"Ulysses","James Joyce"}, {"Ulysses","Dublin"}}; In> writer["Ulysses"]; Out> "James Joyce"; In> AssocDelete(writer,{"Ulysses","James Joyce"}); Out> True; In> writer Out> {{"Iliad","Homer"},{"Ulysses","Dublin"}}; |
Flatten(expression,operator) |
operator -- string with the contents of an infix operator.
In> Flatten(a+b*c+d,"+"); Out> {a,b*c,d}; In> Flatten({a,{b,c},d},"List"); Out> {a,b,c,d}; |
UnFlatten(list,operator,identity) |
operator -- infix operator
identity -- identity of the operator
In> UnFlatten({a,b,c},"+",0) Out> a+b+c; In> UnFlatten({a,b,c},"*",1) Out> a*b*c; |
Type(expr) |
In> Type({a,b,c}); Out> "List"; In> Type(a*(b+c)); Out> "*"; In> Type(123); Out> ""; |
NrArgs(expr) |
In> NrArgs(f(a,b,c)) Out> 3; In> NrArgs(Sin(x)); Out> 1; In> NrArgs(a*(b+c)); Out> 2; |
VarList(expr) VarListArith(expr) VarListSome(expr, list) |
list -- a list of function atoms
The command VarListSome looks only at arguments of functions in the list. All other functions are considered "opaque" (as if they do not contain any variables) and their arguments are not checked. For example, VarListSome(a + Sin(b-c)) will return {a, b, c}, but VarListSome(a*Sin(b-c), {*}) will not look at arguments of Sin() and will return {a,Sin(b-c)}. Here Sin(b-c) is considered a "variable" because the function Sin does not belong to list.
The command VarListArith returns a list of all variables that appear arithmetically in the expression expr. This is implemented through VarListSome by restricting to the arithmetic functions +, -, *, /. Arguments of other functions are not checked.
Note that since the operators "+" and "-" are prefix as well as infix operators, it is currently required to use Atom("+") to obtain the unevaluated atom "+".
In> VarList(Sin(x)) Out> {x}; In> VarList(x+a*y) Out> {x,a,y}; In> VarListSome(x+a*y, {Atom("+")}) Out> {x,a*y}; In> VarListArith(x+y*Cos(Ln(x)/x)) Out> {x,y,Cos(Ln(x)/x)} In> VarListArith(x+a*y^2-1) Out> {x,a,y^2}; |
FuncList(expr) FuncListArith(expr) FuncListSome(expr, list) |
list -- list of function atoms to be considered "transparent"
The command FuncListSome(expr, list) does the same, except it only looks at arguments of a given list of functions. All other functions become "opaque" (as if they do not contain any other functions). For example, FuncListSome(a + Sin(b-c)) will see that the expression has a "-" operation and return {+,Sin,-}, but FuncListSome(a + Sin(b-c), {+}) will not look at arguments of Sin() and will return {+,Sin}.
FuncListArith is defined through FuncListSome to look only at arithmetic operations +, -, *, /.
Note that since the operators "+" and "-" are prefix as well as infix operators, it is currently required to use Atom("+") to obtain the unevaluated atom "+".
In> FuncList(x+y*Cos(Ln(x)/x)) Out> {+,*,Cos,/,Ln}; In> FuncListArith(x+y*Cos(Ln(x)/x)) Out> {+,*,Cos}; In> FuncListSome({a+b*2,c/d},{List}) Out> {List,+,/}; |
BubbleSort(list, compare) HeapSort(list, compare) |
compare -- function used to compare elements of list
The function BubbleSort uses the so-called "bubble sort" algorithm to do the sorting by swapping elements that are out of order. This algorithm is easy to implement, though it is not particularly fast. The sorting time is proportional to n^2 where n is the length of the list.
The function HeapSort uses a recursive algorithm "heapsort" and is much faster for large lists. The sorting time is proportional to n*Ln(n) where n is the length of the list.
In> BubbleSort({4,7,23,53,-2,1}, "<"); Out> {-2,1,4,7,23,53}; In> HeapSort({4,7,23,53,-2,1}, ">"); Out> {53,23,7,4,1,-2}; |
PrintList(list) PrintList(list, padding); |
padding -- (optional) a string
In> PrintList({a,b,{c, d}}, " .. ") Out> " a .. b .. { c .. d}"; |
Table(body, var, from, to, step) |
var -- variable to use as loop variable
from -- initial value for "var"
to -- final value for "var"
step -- step size with which "var" is incremented
In> Table(i!, i, 1, 9, 1); Out> {1,2,6,24,120,720,5040,40320,362880}; In> Table(i, i, 3, 16, 4); Out> {3,7,11,15}; In> Table(i^2, i, 10, 1, -1); Out> {100,81,64,49,36,25,16,9,4,1}; |
TableForm(list) |
In> TableForm(Table(i!, i, 1, 10, 1)); |
1 2 6 24 120 720 5040 40320 362880 3628800 Out> True; |
GlobalPop(var) GlobalPop() GlobalPush(expr) |
expr -- expression, value to save on the stack
GlobalPush stores a value on the stack. GlobalPop removes the last pushed value from the stack. If a variable name is given, the variable is assigned, otherwise the popped value is returned.
If the global stack is empty, an error message is printed.
In> GlobalPush(3) Out> 3; In> GlobalPush(Sin(x)) Out> Sin(x); In> GlobalPop(x) Out> Sin(x); In> GlobalPop(x) Out> 3; In> x Out> 3; |
item : list string1 : string2 |
list -- a list
string1 -- a string
string2 -- a string
In> a:b:c:{} Out> {a,b,c}; In> "This":"Is":"A":"String" Out> "ThisIsAString"; |
fn @ arglist |
arglist -- single argument, or a list of arguments
In> "Sin" @ a Out> Sin(a); In> {{a},Sin(a)} @ a Out> Sin(a); In> "f" @ {a,b} Out> f(a,b); |
fn /@ list |
list -- list of arguments
In> "Sin" /@ {a,b} Out> {Sin(a),Sin(b)}; In> {{a},Sin(a)*a} /@ {a,b} Out> {Sin(a)*a,Sin(b)*b}; |
n .. m |
m -- integer, the last entry in the list
In> 1 .. 4 Out> {1,2,3,4}; |
NFunction("newname","funcname", {arglist}) |
"funcname" -- name of an existing function
arglist -- symbolic list of arguments
This can be useful when plotting functions defined through other Yacas routines that cannot return unevaluated.
If the numerical calculation does not return a number (for example, it might return the atom nan, "not a number", for some arguments), then the new function will return Undefined.
In> f(x) := N(Sin(x)); Out> True; In> NFunction("f1", "f", {x}); Out> True; In> f1(a); Out> f1(a); In> f1(0); Out> 0; |
In> t(x) := If(x<=0.5, 2*x, 2*(1-x)); Out> True; In> t(0.2); Out> 0.4; In> t(x); In function "If" : bad argument number 1 (counting from 1) CommandLine(1) : Invalid argument |
In> NFunction("t1", "t", {x}) Out> True; In> t1(x); Out> t1(x); In> t1(0.2); Out> 0.4; |
In> Plot2D(t1(x), -0.1: 1.1) Out> True; |
expr Where x==v expr Where x1==v1 And x2==v2 And ... expr Where {x1==v1 And x2==v2,x1==v3 And x2==v4,...} |
x - variable to set
v - value to substitute for variable
var1==val1 And var2==val2 And ... |
and fills in the corresponding values. Lists of value pairs are also possible, as:
{var1==val1 And var2==val2, var1==val3 And var2==val4} |
These values might be obtained through Solve.
In> x^2+y^2 Where x==2 Out> y^2+4; In> x^2+y^2 Where x==2 And y==3 Out> 13; In> x^2+y^2 Where {x==2 And y==3} Out> {13}; In> x^2+y^2 Where {x==2 And y==3,x==4 And y==5} Out> {13,41}; |
eq1 AddTo eq2 |
A list a,b means that a is a solution, OR b is a solution. AddTo then acts as a AND operation:
(a or b) and (c or d) => (a or b) Addto (c or d) => (a and c) or (a and d) or (b and c) or (b and d) |
This function is useful for adding an identity to an already existing set of equations. Suppose a solve command returned a>=0 And x==a,a<0 And x== -a from an expression x==Abs(a), then a new identity a==2 could be added as follows:
In> a==2 AddTo {a>=0 And x==a,a<0 And x== -a} Out> {a==2 And a>=0 And x==a,a==2 And a<0 And x== -a}; |
Passing this set of set of identities back to solve, solve should recognize that the second one is not a possibility any more, since a==2 And a<0 can never be true at the same time.
In> {A==2,c==d} AddTo {b==3 And d==2} Out> {A==2 And b==3 And d==2,c==d And b==3 And d==2}; In> {A==2,c==d} AddTo {b==3, d==2} Out> {A==2 And b==3,A==2 And d==2,c==d And b==3,c==d And d==2}; |
MaxEvalDepth(n) |
The point of having a maximum evaluation depth is to catch any infinite recursion. For example, after the definition f(x) := f(x), evaluating the expression f(x) would call f(x), which would call f(x), etc. The interpreter will halt if the maximum evaluation depth is reached. Also indirect recursion, e.g. the pair of definitions f(x) := g(x) and g(x) := f(x), will be caught.
In> f(x) := f(x) Out> True; In> f(x) Error on line 1 in file [CommandLine] Max evaluation stack depth reached. Please use MaxEvalDepth to increase the stack size as needed. |
However, a long calculation may cause the maximum evaluation depth to be reached without the presence of infinite recursion. The function MaxEvalDepth is meant for these cases.
In> 10 # g(0) <-- 1; Out> True; In> 20 # g(n_IsPositiveInteger) <-- \ 2 * g(n-1); Out> True; In> g(1001); Error on line 1 in file [CommandLine] Max evaluation stack depth reached. Please use MaxEvalDepth to increase the stack size as needed. In> MaxEvalDepth(10000); Out> True; In> g(1001); Out> 21430172143725346418968500981200036211228096234 1106721488750077674070210224987224498639675763139171 6255189345835106293650374290571384628087196915514939 7149607869135549648461970842149210124742283755908364 3060929499671638825347975351183310878921541258291423 92955373084335320859663305248773674411336138752; |
Hold(expr) |
The function UnList() also leaves its result unevaluated. Both functions stop the process of evaluation (no more rules will be applied).
In> Echo({ Hold(1+1), "=", 1+1 }); 1+1 = 2 Out> True; |
Eval(expr) |
In> a := x; Out> x; In> x := 5; Out> 5; In> a; Out> x; In> Eval(a); Out> 5; |
The variable a is bound to x, and x is bound to 5. Hence evaluating a will give x. Only when an extra evaluation of a is requested, the value 5 is returned.
Note that the behavior would be different if we had exchanged the assignments. If the assignment a := x were given while x had the value 5, the variable a would also get the value 5 because the assignment operator := evaluates the right-hand side.
While(pred) body |
body -- expression to loop over
In particular, if "pred" immediately evaluates to False, the body is never executed. While is the fundamental looping construct on which all other loop commands are based. It is equivalent to the while command in the programming language C.
In> x := 0; Out> 0; In> While (x! < 10^6) \ [ Echo({x, x!}); x++; ]; 0 1 1 1 2 2 3 6 4 24 5 120 6 720 7 5040 8 40320 9 362880 Out> True; |
Until(pred) body |
body -- expression to loop over
The main difference with While is that Until always evaluates the body at least once, but While may not evaluate the body at all. Besides, the meaning of the predicate is reversed: While stops if "pred" is False while Until stops if "pred" is True. The command Until(pred) body; is equivalent to pred; While(Not pred) body;. In fact, the implementation of Until is based on the internal command While. The Until command can be compared to the do ... while construct in the programming language C.
In> x := 0; Out> 0; In> Until (x! > 10^6) \ [ Echo({x, x!}); x++; ]; 0 1 1 1 2 2 3 6 4 24 5 120 6 720 7 5040 8 40320 9 362880 Out> True; |
If(pred, then) If(pred, then, else) |
then -- expression to evaluate if "pred" is True
else -- expression to evaluate if "pred" is False
In> mysign(x) := If (IsPositiveReal(x), 1, -1); Out> True; In> mysign(Pi); Out> 1; In> mysign(-2.5); Out> -1; |
In> mysign(a); Out> -1; |
In> mysign(_x)_IsNumber(N(x)) <-- If \ (IsPositiveReal(x), 1, -1); Out> True; |
SystemCall(str) |
The SystemCall function is not allowed in the body of the Secure command and will lead to an error.
In> SystemCall("ls") AUTHORS COPYING ChangeLog |
Out> True; |
The standard UNIX command test returns success or failure depending on conditions. For example, the following command will check if a directory exists:
In> SystemCall("test -d scripts/") Out> True; |
Check that a file exists:
In> SystemCall("test -f COPYING") Out> True; In> SystemCall("test -f nosuchfile.txt") Out> False; |
Function() func(arglist) Function() func(arglist, ...) Function("op", {arglist}) body Function("op", {arglist, ...}) body |
"op" -- string, name of the function
{arglist} -- list of atoms, formal arguments to the function
... -- literal ellipsis symbol "..." used to denote a variable number of arguments
body -- expression comprising the body of the function
The number of arguments of the new function and their names are determined by the list arglist. If the ellipsis "..." follows the last atom in arglist, a function with a variable number of arguments is declared (using RuleBaseListed). Note that the ellipsis cannot be the only element of arglist and must be preceded by an atom.
A function with variable number of arguments can take more arguments than elements in arglist; in this case, it obtains its last argument as a list containing all extra arguments.
The short form of the Function call merely declares a RuleBase for the new function but does not define any function body. This is a convenient shorthand for RuleBase and RuleBaseListed, when definitions of the function are to be supplied by rules. If the new function has been already declared with the same number of arguments (with or without variable arguments), Function returns false and does nothing.
The second, longer form of the Function call declares a function and also defines a function body. It is equivalent to a single rule such as op(_arg1, _arg2) <-- body. The rule will be declared at precedence 1025. Any previous rules associated with "op" (with the same arity) will be discarded. More complicated functions (with more than one body) can be defined by adding more rules.
In> Function() f1(x,y,...); Out> True; In> Function() f1(x,y); Out> False; |
This defines a function FirstOf which returns the first element of a list. Equivalent definitions would be FirstOf(_list) <-- list[1] or FirstOf(list) := list[1].
In> Function("FirstOf", {list}) list[1]; Out> True; In> FirstOf({a,b,c}); Out> a; |
The following function will print all arguments to a string:
In> Function("PrintAll",{x, ...}) If(IsList(x), PrintList(x), ToString()Write(x)); Out> True; In> PrintAll(1): Out> " 1"; In> PrintAll(1,2,3); Out> " 1 2 3"; |
Macro() func(arglist) Macro() func(arglist, ...) Macro("op", {arglist}) body Macro("op", {arglist, ...}) body |
"op" -- string, name of the function
{arglist} -- list of atoms, formal arguments to the function
... -- literal ellipsis symbol "..." used to denote a variable number of arguments
body -- expression comprising the body of the function
In> Macro("myfor",{init,pred,inc,body}) [@init;While(@pred)[@body;@inc;];True;]; Out> True; In> a:=10 Out> 10; |
Here this new macro myfor is used to loop, using a variable a from the calling environment.
In> myfor(i:=1,i<10,i++,Echo(a*i)) 10 20 30 40 50 60 70 80 90 Out> True; In> i Out> 10; |
Use(name) |
The purpose of this function is to make sure that the file will at least have been loaded, but is not loaded twice.
For(init, pred, incr) body |
pred -- predicate deciding whether to continue the loop
incr -- expression to increment the counter
body -- expression to loop over
This command is most often used in a form such as For(i=1, i<=10, i++) body, which evaluates body with i subsequently set to 1, 2, 3, 4, 5, 6, 7, 8, 9, and 10.
The expression For(init, pred, incr) body is equivalent to init; While(pred) [body; incr;].
In> For (i:=1, i<=10, i++) Echo({i, i!}); 1 1 2 2 3 6 4 24 5 120 6 720 7 5040 8 40320 9 362880 10 3628800 Out> True; |
ForEach(var, list) body |
list -- list of values to assign to "var"
body -- expression to evaluate with different values of "var"
In> ForEach(i,{2,3,5,7,11}) Echo({i, i!}); 2 2 3 6 5 120 7 5040 11 39916800 Out> True; |
Apply(fn, arglist) |
arglist -- list of arguments
An shorthand for Apply is provided by the @ operator.
In> Apply("+", {5,9}); Out> 14; In> Apply({{x,y}, x-y^2}, {Cos(a), Sin(a)}); Out> Cos(a)-Sin(a)^2; |
MapArgs(expr, fn) |
fn -- an operation to perform on each argument
In> MapArgs(f(x,y,z),"Sin"); Out> f(Sin(x),Sin(y),Sin(z)); In> MapArgs({3,4,5,6}, {{x},x^2}); Out> {9,16,25,36}; |
Subst(from, to) expr |
to -- expression to substitute for "from"
expr -- expression in which the substitution takes place
In> Subst(x, Sin(y)) x^2+x+1; Out> Sin(y)^2+Sin(y)+1; In> Subst(a+b, x) a+b+c; Out> x+c; In> Subst(b+c, x) a+b+c; Out> a+b+c; |
The explanation for the last result is that the expression a+b+c is internally stored as (a+b)+c. Hence a+b is a subexpression, but b+c is not.
WithValue(var, val, expr) WithValue({var,...}, {val,...}, expr) |
val -- value to be assigned to "var"
expr -- expression to evaluate with "var" equal to "val"
The second calling sequence assigns the first element in the list of values to the first element in the list of variables, the second value to the second variable, etc.
In> WithValue(x, 3, x^2+y^2+1); Out> y^2+10; In> WithValue({x,y}, {3,2}, x^2+y^2+1); Out> 14; |
expression /: patterns expressions /:: patterns |
patterns -- a list of patterns
In> Sin(x)*Ln(a*b) Out> Sin(x)*Ln(a*b); In> % /: { Ln(_x*_y) <- Ln(x)+Ln(y) } Out> Sin(x)*(Ln(a)+Ln(b)); |
A whole list of simplification rules can be built up in the list, and they will be applied to the expression on the left hand side of /: .
The forms the patterns can have are one of:
pattern <- replacement {pattern,replacement} {pattern,postpredicate,replacement} |
Note that for these local rules, <- should be used instead of <-- which would be used in a global rule.
The /: operator traverses an expression much as Subst does, that is, top down, trying to apply the rules from the beginning of the list of rules to the end of the list of rules. If the rules cannot be applied to an expression, it will try subexpressions of that expression and so on.
It might be necessary sometimes to use the /:: operator, which repeatedly applies the /: operator until the result doesn't change any more. Caution is required, since rules can contradict each other, which could result in an infinite loop. To detect this situation, just use /: repeatedly on the expression. The repetitive nature should become apparent.
In> Sin(u)*Ln(a*b) /: {Ln(_x*_y) <- Ln(x)+Ln(y)} Out> Sin(u)*(Ln(a)+Ln(b)); In> Sin(u)*Ln(a*b) /:: { a <- 2, b <- 3 } Out> Sin(u)*Ln(6); |
SetHelpBrowser(helpbrowser) |
In> SetHelpBrowser("netscape") Out> "netscape"; In> ?? |
TraceStack(expression) |
For each stack frame, it shows if the function evaluated was a built-in function or a user-defined function, and for the user-defined function, the number of the rule it is trying whether it was evaluating the pattern matcher of the rule, or the body code of the rule.
This functionality is not offered by default because it slows down the evaluation code.
In> f(x):=f(Sin(x)) Out> True; In> TraceStack(f(2)) Debug> 982 : f (Rule # 0 in body) Debug> 983 : f (Rule # 0 in body) Debug> 984 : f (Rule # 0 in body) Debug> 985 : f (Rule # 0 in body) Debug> 986 : f (Rule # 0 in body) Debug> 987 : f (Rule # 0 in body) Debug> 988 : f (Rule # 0 in body) Debug> 989 : f (Rule # 0 in body) Debug> 990 : f (Rule # 0 in body) Debug> 991 : f (Rule # 0 in body) Debug> 992 : f (Rule # 0 in body) Debug> 993 : f (Rule # 0 in body) Debug> 994 : f (Rule # 0 in body) Debug> 995 : f (User function) Debug> 996 : Sin (Rule # 0 in pattern) Debug> 997 : IsList (Internal function) Error on line 1 in file [CommandLine] Max evaluation stack depth reached. Please use MaxEvalDepth to increase the stack size as needed. |
TraceExp(expr) |
Note that this command usually generates huge amounts of output. A more specific form of tracing (eg. TraceRule) is probably more useful for all but very simple expressions.
In> TraceExp(2+3); TrEnter(2+3); TrEnter(2); TrLeave(2, 2); TrEnter(3); TrLeave(3, 3); TrEnter(IsNumber(x)); TrEnter(x); TrLeave(x, 2); TrLeave(IsNumber(x),True); TrEnter(IsNumber(y)); TrEnter(y); TrLeave(y, 3); TrLeave(IsNumber(y),True); TrEnter(True); TrLeave(True, True); TrEnter(MathAdd(x,y)); TrEnter(x); TrLeave(x, 2); TrEnter(y); TrLeave(y, 3); TrLeave(MathAdd(x,y),5); TrLeave(2+3, 5); Out> 5; |
TraceRule(template) expr |
expr -- expression to evaluate with tracing on
This is useful for tracing a function that is called from within another function. This way you can see how your function behaves in the environment it is used in.
In> TraceRule(x+y) 2+3*5+4; TrEnter(2+3*5+4); TrEnter(2+3*5); TrArg(2, 2); TrArg(3*5, 15); TrLeave(2+3*5, 17); TrArg(2+3*5, 17); TrArg(4, 4); TrLeave(2+3*5+4, 21); Out> 21; |
Time(expr) |
The result is the "user time" as reported by the OS, not the real ("wall clock") time. Therefore, any CPU-intensive processes running alongside Yacas will not significantly affect the result of Time.
In> Time([Precision(40);MathLog(1000);]) 0.34 seconds taken Out> 6.9077552789821370520539743640530926228033; |
e1 < e2 |
The word "numeric" in the previous paragraph has the following meaning. An expression is numeric if it is either a number (i.e. IsNumber returns True), or the quotient of two numbers, or an infinity (i.e. IsInfinity returns True).
In> 2 < 5; Out> True; In> Cos(1) < 5; Out> Cos(1)<5; In> N(Cos(1)) < 5; Out> True |
e1 > e2 |
The word "numeric" in the previous paragraph has the following meaning. An expression is numeric if it is either a number (i.e. IsNumber returns True), or the quotient of two numbers, or an infinity (i.e. IsInfinity returns True).
In> 2 > 5; Out> False; In> Cos(1) > 5; Out> Cos(1)>5; In> N(Cos(1)) > 5; Out> False |
e1 <= e2 |
The word "numeric" in the previous paragraph has the following meaning. An expression is numeric if it is either a number (i.e. IsNumber returns True), or the quotient of two numbers, or an infinity (i.e. IsInfinity returns True).
In> 2 <= 5; Out> True; In> Cos(1) <= 5; Out> Cos(1)<=5; In> N(Cos(1)) <= 5; Out> True |
e1 >= e2 |
The word "numeric" in the previous paragraph has the following meaning. An expression is numeric if it is either a number (i.e. IsNumber returns True), or the quotient of two numbers, or an infinity (i.e. IsInfinity returns True).
In> 2 >= 5; Out> False; In> Cos(1) >= 5; Out> Cos(1)>=5; In> N(Cos(1)) >= 5; Out> False |
e1 != e2 |
The expression e1 != e2 is equivalent to Not(e1 = e2).
In> 1 != 2; Out> True; In> 1 != 1; Out> False; |
e1 = e2 |
Note that the test is on syntactic equality, not mathematical equality. Hence even if the result is False, the expressions can still be mathematically equal; see the examples below. Put otherwise, this function tests whether the two expressions would be displayed in the same way if they were printed.
In> e1 := (x+1) * (x-1); Out> (x+1)*(x-1); In> e2 := x^2 - 1; Out> x^2-1; In> e1 = e2; Out> False; In> Expand(e1) = e2; Out> True; |
Not expr |
In> Not True Out> False; In> Not False Out> True; In> Not(a) Out> Not a; |
a1 And a2 |
And(a1, a2, a3, ..., aN) |
In> True And False Out> False; In> And(True,True) Out> True; In> False And a Out> False; In> True And a Out> And(a); In> And(True,a,True,b) Out> b And a; |
a1 Or a2 |
Or(a1, a2, a3, ..., aN) |
In> True Or False Out> True; In> False Or a Out> Or(a); In> Or(False,a,b,True) Out> True; |
IsFreeOf(var, expr) IsFreeOf({var, ...}, expr) |
var -- variable to look for in "expr"
The second form test whether the expression depends on any of the variables named in the list. The result is True if none of the variables appear in the expression and False otherwise.
In> IsFreeOf(x, Sin(x)); Out> False; In> IsFreeOf(y, Sin(x)); Out> True; In> IsFreeOf(x, D(x) a*x+b); Out> True; In> IsFreeOf({x,y}, Sin(x)); Out> False; |
The third command returns True because the expression D(x) a*x+b evaluates to a, which does not depend on x.
IsZeroVector(list) |
In> IsZeroVector({0, x, 0}); Out> False; In> IsZeroVector({x-x, 1 - D(x) x}); Out> True; |
IsNonObject(expr) |
IsEven(n) |
In> IsEven(4); Out> True; In> IsEven(-1); Out> False; |
IsOdd(n) |
In> IsOdd(4); Out> False; In> IsOdd(-1); Out> True; |
IsEvenFunction(expression,variable) IsOddFunction(expression,variable) |
And odd functions have the property:
Sin(x) is an example of an odd function, and Cos(x) is an example of an even function.
As a side note, one can decompose a function into an even and an odd part:
Where
and
In> IsEvenFunction(Cos(b*x),x) Out> True In> IsOddFunction(Cos(b*x),x) Out> False In> IsOddFunction(Sin(b*x),x) Out> True In> IsEvenFunction(Sin(b*x),x) Out> False In> IsEvenFunction(1/x^2,x) Out> True In> IsEvenFunction(1/x,x) Out> False In> IsOddFunction(1/x,x) Out> True In> IsOddFunction(1/x^2,x) Out> False |
IsFunction(expr) |
In> IsFunction(x+5); Out> True; In> IsFunction(x); Out> False; |
IsAtom(expr) |
In> IsAtom(x+5); Out> Falso; In> IsAtom(5); Out> True; |
IsString(expr) |
In> IsString("duh"); Out> True; In> IsString(duh); Out> False; |
IsNumber(expr) |
In> IsNumber(6); Out> True; In> IsNumber(3.25); Out> True; In> IsNumber(I); Out> False; In> IsNumber("duh"); Out> False; |
IsList(expr) |
In> IsList({2,3,5}); Out> True; In> IsList(2+3+5); Out> False; |
IsNumericList({list}) |
IsBound(var) |
In> IsBound(x); Out> False; In> x := 5; Out> 5; In> IsBound(x); Out> True; |
IsBoolean(expression) |
In> IsBoolean(a) Out> False; In> IsBoolean(True) Out> True; In> IsBoolean(a And b) Out> True; |
IsNegativeNumber(n) |
In> IsNegativeNumber(6); Out> False; In> IsNegativeNumber(-2.5); Out> True; |
IsNegativeInteger(n) |
In> IsNegativeInteger(31); Out> False; In> IsNegativeInteger(-2); Out> True; |
IsPositiveNumber(n) |
In> IsPositiveNumber(6); Out> True; In> IsPositiveNumber(-2.5); Out> False; |
IsPositiveInteger(n) |
In> IsPositiveInteger(31); Out> True; In> IsPositiveInteger(-2); Out> False; |
IsNotZero(n) |
In> IsNotZero(3.25); Out> True; In> IsNotZero(0); Out> False; |
IsNonZeroInteger(n) |
In> IsNonZeroInteger(0) Out> False; In> IsNonZeroInteger(-2) Out> True; |
IsInfinity(expr) |
In> IsInfinity(10^1000); Out> False; In> IsInfinity(-Infinity); Out> True; |
IsPositiveReal(expr) |
In> IsPositiveReal(Sin(1)-3/4); Out> True; In> IsPositiveReal(Sin(1)-6/7); Out> False; In> IsPositiveReal(Exp(x)); Out> False; |
The last result is because Exp(x) cannot be numerically approximated if x is not known. Hence Yacas can not determine the sign of this expression.
IsNegativeReal(expr) |
In> IsNegativeReal(Sin(1)-3/4); Out> False; In> IsNegativeReal(Sin(1)-6/7); Out> True; In> IsNegativeReal(Exp(x)); Out> False; |
The last result is because Exp(x) cannot be numerically approximated if x is not known. Hence Yacas can not determine the sign of this expression.
IsConstant(expr) |
In> IsConstant(Cos(x)) Out> False; In> IsConstant(Cos(2)) Out> True; In> IsConstant(Cos(2+x)) Out> False; |
IsGaussianInteger(z) |
In> IsGaussianInteger(5) Out> True; In> IsGaussianInteger(5+6*I) Out> True; In> IsGaussianInteger(1+2.5*I) Out> False; |
MatchLinear(x,expr) |
expr -- expression to match
In> MatchLinear(x,(R+1)*x+(T-1)) Out> True; In> {a,b}; Out> {R+1,T-1}; In> MatchLinear(x,Sin(x)*x+(T-1)) Out> False; |
HasExpr(expr, x) HasExprArith(expr, x) HasExprSome(expr, x, list) |
x -- a subexpression to be found
list -- list of function atoms to be considered "transparent"
The command HasExprSome does the same, except it only looks at arguments of a given list of functions. All other functions become "opaque" (as if they do not contain anything).
HasExprArith is defined through HasExprSome to look only at arithmetic operations +, -, *, /.
Note that since the operators "+" and "-" are prefix as well as infix operators, it is currently required to use Atom("+") to obtain the unevaluated atom "+".
In> HasExpr(x+y*Cos(Ln(z)/z), z) Out> True; In> HasExpr(x+y*Cos(Ln(z)/z), Ln(z)) Out> True; In> HasExpr(x+y*Cos(Ln(z)/z), z/Ln(z)) Out> False; In> HasExprArith(x+y*Cos(Ln(x)/x), z) Out> False; In> HasExprSome({a+b*2,c/d},c/d,{List}) Out> True; In> HasExprSome({a+b*2,c/d},c,{List}) Out> False; |
HasFunc(expr, func) HasFuncArith(expr, func) HasFuncSome(expr, func, list) |
func -- a function atom to be found
list -- list of function atoms to be considered "transparent"
The command HasFuncSome does the same, except it only looks at arguments of a given list of functions. Arguments of all other functions become "opaque" (as if they do not contain anything).
HasFuncArith is defined through HasFuncSome to look only at arithmetic operations +, -, *, /.
Note that since the operators "+" and "-" are prefix as well as infix operators, it is currently required to use Atom("+") to obtain the unevaluated atom "+".
In> HasFunc(x+y*Cos(Ln(z)/z), Ln) Out> True; In> HasFunc(x+y*Cos(Ln(z)/z), Sin) Out> False; In> HasFuncArith(x+y*Cos(Ln(x)/x), Cos) Out> True; In> HasFuncArith(x+y*Cos(Ln(x)/x), Ln) Out> False; In> HasFuncSome({a+b*2,c/d},/,{List}) Out> True; In> HasFuncSome({a+b*2,c/d},*,{List}) Out> False; |
CanProve(proposition) |
An example of a proposition is: "if a implies b and b implies c then a implies c". Yacas supports the following logical operations:
Not : negation, read as "not"
And : conjunction, read as "and"
Or : disjunction, read as "or"
=> : implication, read as "implies"
The abovementioned proposition would be represented by the following expression,
( (a=>b) And (b=>c) ) => (a=>c) |
Yacas can prove that is correct by applying CanProve to it:
In> CanProve(( (a=>b) And (b=>c) ) => (a=>c)) Out> True; |
It does this in the following way: in order to prove a proposition p, it suffices to prove that Not p is false. It continues to simplify Not p using the rules:
Not ( Not x) --> x |
x=>y --> Not x Or y |
Not (x And y) --> Not x Or Not y |
Not (x Or y) --> Not x And Not y |
(x And y) Or z --> (x Or z) And (y Or z) |
x Or (y And z) --> (x Or y) And (x Or z) |
True Or x --> True |
(p1 Or p2 Or ...) And (q1 Or q2 Or ...) And ... |
(p Or Y) And ( Not p Or Z) --> (Y Or Z) |
As a last step, the algorithm negates the result again. This has the added advantage of simplifying the expression further.
In> CanProve(a Or Not a) Out> True; In> CanProve(True Or a) Out> True; In> CanProve(False Or a) Out> a; In> CanProve(a And Not a) Out> False; In> CanProve(a Or b Or (a And b)) Out> a Or b; |
% |
Typical examples are Simplify(%) and PrettyForm(%) to simplify and show the result in a nice form respectively.
In> Taylor(x,0,5)Sin(x) Out> x-x^3/6+x^5/120; In> PrettyForm(%) 3 5 x x x - -- + --- 6 120 |
True False |
EndOfFile |
Infinity |
Note that for most analytic functions Yacas understands Infinity as a positive number. Thus Infinity*2 will return Infinity, and a < Infinity will evaluate to True.
In> 2*Infinity Out> Infinity; In> 2<Infinity Out> True; |
Pi |
This is a "cached constant" which is recalculated only when precision is increased.
In> Sin(3*Pi/2) Out> -1; In> Sin(3*Pi()/2) Out> Sin(4.7123889804); In> Pi+1 Out> Pi+1; In> N(Pi) Out> 3.14159265358979323846; |
Undefined |
Most functions also return Undefined when evaluated on it.
In> 2*Infinity Out> Infinity; In> 0*Infinity Out> Undefined; In> Sin(Infinity); Out> Undefined; In> Undefined+2*Exp(Undefined); Out> Undefined; |
var := expr {var1, var2, ...} := {expr1, expr2, ...} var[i] := expr fn(arg1, arg2, ...) := expr |
expr -- expression to assign to the variable or body of function
i -- index (can be integer or string)
fn -- atom, name of a new function to define
arg1, arg2 -- atoms, names of arguments of the new function fn
The first form is the most basic one. It evaluates the expression on the right-hand side and assigns it to the variable named on the left-hand side. The left-hand side is not evaluated. The evaluated expression is also returned.
The second form is a small extension, which allows one to do multiple assignments. The first entry in the list on the right-hand side is assigned to the first variable mentioned in the left-hand side, the second entry on the right-hand side to the second variable on the left-hand side, etc. The list on the right-hand side must have at least as many entries as the list on the left-hand side. Any excess entries are silently ignored. The result of the expression is the list of values that have been assigned.
The third form allows one to change an entry in the list. If the index "i" is an integer, the "i"-th entry in the list is changed to the expression on the right-hand side. It is assumed that the length of the list is at least "i". If the index "i" is a string, then "var" is considered to be an associative list (sometimes called hash table), and the key "i" is paired with the value "exp". In both cases, the right-hand side is evaluated before the assignment and the result of the assignment is True.
The last form defines a function. For example, the assignment fn(x) := x^2 removes any rules previously associated with fn(x) and defines the rule fn(_x) <-- x^2. Note that the left-hand side may take a different form if fn is defined to be a prefix, infix or bodied function. This case is special since the right-hand side is not evaluated immediately, but only when the function fn is used. If this takes time, it may be better to force an immediate evaluation with Eval (see the last example). If the expression on the right hand side begins with Eval(), then it will be evaluated before defining the new function.
A variant of the function definition can be used to make a function accepting a variable number of arguments. The last argument
In> a := Sin(x) + 3; Out> Sin(x)+3; In> a; Out> Sin(x)+3; |
Multiple assignments:
In> {a,b,c} := {1,2,3}; Out> {1,2,3}; In> a; Out> 1; In> b+c; Out> 5; |
Assignment to a list:
In> xs := { 1,2,3,4,5 }; Out> {1,2,3,4,5}; In> xs[3] := 15; Out> True; In> xs; Out> {1,2,15,4,5}; |
Building an associative list:
In> alist := {}; Out> {}; In> alist["cherry"] := "red"; Out> True; In> alist["banana"] := "yellow"; Out> True; In> alist["cherry"]; Out> "red"; In> alist; Out> {{"banana","yellow"},{"cherry","red"}}; |
Defining a function:
In> f(x) := x^2; Out> True; In> f(3); Out> 9; In> f(Sin(a)); Out> Sin(a)^2; |
Defining a function with variable number of arguments:
In> f(x, ...) := If(IsList(x),Sum(x),x); Out> True; In> f(2); Out> 2; In> f(1,2,3); Out> 6; |
Defining a new infix operator:
In> Infix("*&*",10); Out> True; In> x1 *&* x2 := x1/x2 + x2/x1; Out> True; In> Sin(a) *&* Cos(a); Out> Tan(1)+Cos(1)/Sin(1); In> Clear(a); Out> True; In> Sin(a) *&* Exp(a); Out> Sin(a)/Exp(a)+Exp(a)/Sin(a); |
In the following example, it may take some time to compute the Taylor expansion. This has to be done every time the function f is called.
In> f(a) := Taylor(x,0,25) Sin(x); Out> True; In> f(1); Out> x-x^3/6+x^5/120-x^7/5040+x^9/362880- x^11/39916800+x^13/6227020800-x^15/ 1307674368000+x^17/355687428096000-x^19/ 121645100408832000+x^21/51090942171709440000 -x^23/25852016738884976640000+x^25 /15511210043330985984000000; In> f(2); Out> x-x^3/6+x^5/120-x^7/5040+x^9/362880- x^11/39916800+x^13/6227020800-x^15 /1307674368000+x^17/355687428096000-x^19/ 121645100408832000+x^21/51090942171709440000 -x^23/25852016738884976640000+x^25/ 15511210043330985984000000; |
The remedy is to evaluate the Taylor expansion immediately. Now the expansion is computed only once.
In> f(a) := Eval(Taylor(x,0,25) Sin(x)); Out> True; In> f(1); Out> x-x^3/6+x^5/120-x^7/5040+x^9/362880- x^11/39916800+x^13/6227020800-x^15/ 1307674368000+x^17/355687428096000-x^19/ 121645100408832000+x^21/51090942171709440000 -x^23/25852016738884976640000+x^25 /15511210043330985984000000; In> f(2); Out> x-x^3/6+x^5/120-x^7/5040+x^9/362880- x^11/39916800+x^13/6227020800-x^15 /1307674368000+x^17/355687428096000-x^19/ 121645100408832000+x^21/51090942171709440000 -x^23/25852016738884976640000+x^25/ 15511210043330985984000000; |
Set(var, exp) |
exp -- expression to assign to the variable
The statement Set(var, exp) is equivalent to var := exp, but the := operator has more uses, e.g. changing individual entries in a list.
In> Set(a, Sin(x)+3); Out> True; In> a; Out> Sin(x)+3; |
Clear(var, ...) |
In> a := 5; Out> 5; In> a^2; Out> 25; In> Clear(a); Out> True; In> a^2; Out> a^2; |
Local(var, ...) |
By default, all variables in Yacas are global. This means that the variable has the same value everywhere. But sometimes it is useful to have a private copy of some variable, either to prevent the outside world from changing it or to prevent accidental changes to the outside world. This can be achieved by declaring the variable local. Now only expressions within the Prog block (or its syntactic equivalent, the [ ] block) can access and change it. Functions called within this block cannot access the local copy unless this is specifically allowed with UnFence.
In> a := 3; Out> 3; In> [ a := 4; a; ]; Out> 4; In> a; Out> 4; In> [ Local(a); a := 5; a; ]; Out> 5; In> a; Out> 4; |
In the first block, a is not declared local and hence defaults to be a global variable. Indeed, changing the variable inside the block also changes the value of a outside the block. However, in the second block a is defined to be local and now the value outside the block stays the same, even though a is assigned the value 5 inside the block.
var++ |
In> x := 5; Out> 5; In> x++; Out> True; In> x; Out> 6; |
var-- |
In> x := 5; Out> 5; In> x--; Out> True; In> x; Out> 4; |
Object("pred", exp) |
exp -- expression on which "pred" should be applied
In> a := Object("IsNumber", x); Out> Object("IsNumber",x); In> Eval(a); Out> Object("IsNumber",x); In> x := 5; Out> 5; In> Eval(a); Out> 5; |
LazyGlobal(var) |
Places where this is used include the global variables % and I.
The use of lazy in the name stems from the concept of lazy evaluation. The object the global variable is bound to will only be evaluated when called. The LazyGlobal property only holds once: after that, the result of evaluation is stored in the global variable, and it won't be reevaluated again:
In> a:=Hold(Taylor(x,0,30)Sin(x)) Out> Taylor(x,0,30)Sin(x); In> LazyGlobal(a) |
Then the first time you call a it evaluates Taylor(...) and assigns the result to a. The next time you call a it immediately returns the result. LazyGlobal is called for % each time % changes.
In> a:=Hold(2+3) Out> 2+3; In> a Out> 2+3; In> LazyGlobal(a) Out> True; In> a Out> 5; |
UniqueConstant() |
In> UniqueConstant() Out> C9 In> UniqueConstant() Out> C10 |
FullForm(expr) |
This can be useful if you want to study the internal representation of a certain expression.
In> FullForm(a+b+c); (+ (+ a b )c ) Out> a+b+c; In> FullForm(2*I*b^2); (* (Complex 0 2 )(^ b 2 )) Out> Complex(0,2)*b^2; |
The first example shows how the expression a+b+c is internally represented. In the second example, 2*I is first evaluated to Complex(0,2) before the expression is printed.
Echo(item) Echo(list) Echo(item,item,item,...) |
list -- a list of items to be printed
If there is one argument, and it is a list, Echo will print all the entries in the list subsequently to the current output, followed by a newline. Any strings in the list are printed without quotation marks. All other entries are followed by a space.
Echo can be called with a variable number of arguments, they will all be printed, followed by a newline.
Echo always returns True.
In> Echo(5+3); 8 Out> True; In> Echo({"The square of two is ", 2*2}); The square of two is 4 Out> True; In> Echo("The square of two is ", 2*2); The square of two is 4 Out> True; |
Note that one must use the second calling format if one wishes to print a list:
In> Echo({a,b,c}); a b c Out> True; In> Echo({{a,b,c}}); {a,b,c} Out> True; |
PrettyForm(expr) |
In> Taylor(x,0,9)Sin(x) Out> x-x^3/6+x^5/120-x^7/5040+x^9/362880; In> PrettyForm(%) 3 5 7 9 x x x x x - -- + --- - ---- + ------ 6 120 5040 362880 Out> True; |
EvalFormula(expr) |
In> EvalFormula(Taylor(x,0,7)Sin(x)) 3 5 x x Taylor( x , 0 , 5 , Sin( x ) ) = x - -- + --- 6 120 |
TeXForm(expr) |
In> TeXForm(Sin(a1)+2*Cos(b1)) Out> "$\sin a_{1} + 2 \cos b_{1}$"; |
CForm(expr) |
In> CForm(Sin(a1)+2*Cos(b1)); Out> "sin(a1) + 2 * cos(b1)"; |
IsCFormable(expr) IsCFormable(expr, funclist) |
funclist -- list of "allowed" function atoms
A Yacas expression is considered exportable if it contains only functions that can be translated into C++ (e.g. UnList cannot be exported). All variables and constants are considered exportable.
The verbose option prints names of functions that are not exportable.
The second calling format of IsCFormable can be used to "allow" certain function names that will be available in the C++ code.
In> IsCFormable(Sin(a1)+2*Cos(b1)) Out> True; In> V(IsCFormable(1+func123(b1))) IsCFormable: Info: unexportable function(s): func123 Out> False; |
In> IsCFormable(1+func123(b1), {func123}) Out> True; |
Write(expr, ...) |
In> Write(1); 1Out> True; In> Write(1,2); 1 2Out> True; |
Write does not write a newline, so the Out> prompt immediately follows the output of Write.
WriteString(string) |
In> Write("Hello, world!"); "Hello, world!"Out> True; In> WriteString("Hello, world!"); Hello, world!Out> True; |
This example clearly shows the difference between Write and WriteString. Note that Write and WriteString do not write a newline, so the Out> prompt immediately follows the output.
Space() Space(nr) |
In> Space(5); Out> True; |
NewLine() NewLine(nr) |
In> NewLine(); Out> True; |
FromFile(name) body |
body - expression to be evaluated
2 + 5; |
Then we can have the following dialogue:
In> FromFile("foo") res := Read(); Out> 2+5; In> FromFile("foo") res := ReadToken(); Out> 2; |
FromString(str) body; |
body -- expression to be evaluated
In> FromString("2+5; this is never read") \ res := Read(); Out> 2+5; In> FromString("2+5; this is never read") \ res := Eval(Read()); Out> 7; |
ToFile(name) body |
body -- expression to be evaluated
If the file is opened again, the old contents will be overwritten. This is a limitation of ToFile: one cannot append to a file that has already been created.
In> ToFile("expr1.c") WriteString( CForm(Sqrt(x-y)*Sin(x)) ); Out> True; |
sqrt(x-y)*sin(x) |
As another example, take a look at the following command:
In> [ Echo("Result:"); \ PrettyForm(Taylor(x,0,9) Sin(x)); ]; Result: 3 5 7 9 x x x x x - -- + --- - ---- + ------ 6 120 5040 362880 Out> True; |
Now suppose one wants to send the output of this command to a file. This can be achieved as follows:
In> ToFile("out") [ Echo("Result:"); \ PrettyForm(Taylor(x,0,9) Sin(x)); ]; Out> True; |
After this command the file out contains:
Result: 3 5 7 9 x x x x x - -- + --- - ---- + ------ 6 120 5040 362880 |
ToString() body |
In> str := ToString() [ WriteString( \ "The square of 8 is "); Write(8^2); ]; Out> "The square of 8 is 64"; |
Read() |
In> FromString("2+5;") Read(); Out> 2+5; In> FromString("") Read(); Out> EndOfFile; |
ToStdout() body |
In> ToString()[Echo("aaaa");ToStdout()Echo("bbbb");]; bbbb Out> "aaaa " |
ReadCmdLineString(prompt) |
The result is returned in a string, so it still needs to be parsed.
This function will typically be used in situations where one wants a custom read-eval-print loop.
In> ReEvPr() := \ In> While(True) [ \ In> PrettyForm(Deriv(x) \ In> FromString(ReadCmdLineString("Deriv> "):";")Read()); \ In> ]; Out> True; |
Then one can invoke the command, from which the following interaction might follow:
In> ReEvPr() Deriv> Sin(a^2*x/b) / 2 \ | a * x | 2 Cos| ------ | * a * b \ b / ---------------------- 2 b Deriv> Sin(x) Cos( x ) Deriv> |
LispRead() LispReadListed() |
The Yacas expression a+b is written in the LISP syntax as (+ a b). The advantage of this syntax is that it is less ambiguous than the infix operator grammar that Yacas uses by default.
The function LispReadListed reads a LISP expression and returns it in a list, instead of the form usual to Yacas (expressions). The result can be thought of as applying Listify to LispRead. The function LispReadListed is more useful for reading arbitrary LISP expressions, because the first object in a list can be itself a list (this is never the case for Yacas expressions where the first object in a list is always a function atom).
In> FromString("(+ a b)") LispRead(); Out> a+b; In> FromString("(List (Sin x) (- (Cos x)))") \ LispRead(); Out> {Sin(x),-Cos(x)}; In> FromString("(+ a b)")LispRead() Out> a+b; In> FromString("(+ a b)")LispReadListed() Out> {+,a,b}; |
ReadToken() |
A token is for computer languages what a word is for human languages: it is the smallest unit in which a command can be divided, so that the semantics (that is the meaning) of the command is in some sense a combination of the semantics of the tokens. Hence a := foo consists of three tokens, namely a, :=, and foo.
The parsing of the string depends on the syntax of the language. The part of the kernel that does the parsing is the "tokenizer". Yacas can parse its own syntax (the default tokenizer) or it can be instructed to parse XML or C++ syntax using the directives DefaultTokenizer, XmlTokenizer, or CTokenizer. Setting a tokenizer is a global action that affects all ReadToken calls.
In> FromString("a := Sin(x)") While \ ((tok := ReadToken()) != EndOfFile) \ Echo(tok); a := Sin ( x ) Out> True; |
We can read some junk too:
In> FromString("-$3")ReadToken(); Out> -$; |
Load(name) |
Use(name) |
The purpose of this function is to make sure that the file will at least have been loaded, but is not loaded twice.
DefLoad(name) |
FindFile(name) |
FindFile("") returns the name of the default directory (the first one on the search path).
PatchLoad(name) |
This is similar to the way PHP works. You can have a static text file with dynamic content generated by Yacas.
Nl() |
Note that the second letter in the name of this command is a lower case L (from "line").
In> WriteString("First line" : Nl() : "Second line" : Nl()); First line Second line Out> True; |
V(expression) |
The function is currently implemented using a global variable Verbose which can be set to True or False.
In> OldSolve({x+2==0},{x}) Out> {{-2}}; In> V(OldSolve({x+2==0},{x})) Entering OldSolve From x+2==0 it follows that x = -2 x+2==0 simplifies to True Leaving OldSolve Out> {{-2}}; |
Plot2D(f(x)) Plot2D(f(x), a:b) Plot2D(f(x), a:b, option=value) Plot2D(f(x), a:b, option=value, ...) Plot2D(list, ...) |
list -- list of functions to plot
a, b -- numbers, plotting range in the x coordinate
option -- atom, option name
value -- atom, number or string (value of option)
The function parameter f(x) must evaluate to a Yacas expression containing at most one variable. (The variable does not have to be called x.) Also, N(f(x)) must evaluate to a real (not complex) numerical value when given a numerical value of the argument x. If the function f(x) does not satisfy these requirements, an error is raised.
Several functions may be specified as a list and they do not have to depend on the same variable, for example, {f(x), g(y)}. The functions will be plotted on the same graph using the same coordinate ranges.
If you have defined a function which accepts a number but does not accept an undefined variable, Plot2D will fail to plot it. Use NFunction to overcome this difficulty.
Data files are created in a temporary directory /tmp/plot.tmp/ unless otherwise requested. File names and other information is printed if the Verbose option is switched on using V().
The current algorithm uses Newton-Cotes quadratures and some heuristics for error estimation (see The Yacas book of algorithms, Chapter 3, Section 1 ). The initial grid of points+1 points is refined between any grid points a, b if the integral Integrate(x,a,b)f(x) is not approximated to the given precision by the existing grid.
Default plotting range is -5:5. Range can also be specified as x= -5:5 (note the mandatory space separating "=" and "-"); currently the variable name x is ignored in this case.
Options are of the form option=value. Currently supported option names are: "points", "precision", "depth", "output", "filename", "yrange". Option values are either numbers or special unevaluated atoms such as data. If you need to use the names of these atoms in your script, strings can be used (e.g. output="gnuplot"). Several option/value pairs may be specified (the function Plot2D has a variable number of arguments).
Other options may be supported in the future.
The current implementation can deal with a singularity within the plotting range only if the function f(x) returns Infinity, -Infinity or Undefined at the singularity. If the function f(x) generates a numerical error and fails at a singularity, Plot2D will fail if one of the grid points falls on the singularity. (All grid points are generated by bisection so in principle the endpoints and the points parameter could be chosen to avoid numerical singularities.)
*WIN32
On the Wind*ws platforms, there are some limitations:
In> Plot2D({(2+x)/(2-x),Exp(y)},-1.8:1.5) Out> True; In> V(Plot2D(Sin(1/x),0:1, depth=4, \ In> precision=0.001, output=plotutils)) Plot2D: using 65 points for function Sin(1/x) Plot2D'datafile: created file '/tmp/plot.tmp/data1' Out> True; |
If a function takes a long time to evaluate, one can use MakeFunctionPlugin (a Unix-specific tool) to compile the function and plot it faster:
In> f(x) := Cos( (Abs(Pi/x))^1.5 ) Out> True; In> Time( Plot2D(f(x),0:1) ) 94.93 seconds taken Out> True; In> MakeFunctionPlugin("f1", f(x)) Function f1(x) loaded from plugins.tmp/ libf1_plugin_cc.so Out> True; In> Time( Plot2D(f1(x),0:1) ) 6.97 seconds taken Out> True; |
Plot3DS(f(x,y)) Plot3DS(f(x,y), a:b, c:d) Plot3DS(f(x,y), a:b, c:d, option=value) Plot3DS(f(x,y), a:b, c:d, option=value, ...) Plot3DS(list, ...) |
list -- list of functions to plot
a, b, c, d -- numbers, plotting ranges in the x and y coordinates
option -- atom, option name
value -- atom, number or string (value of option)
The function parameter f(x,y) must evaluate to a Yacas expression containing at most two variables. (The variables do not have to be called x and y.) Also, N(f(x,y)) must evaluate to a real (not complex) numerical value when given numerical values of the arguments x, y. If the function f(x,y) does not satisfy these requirements, an error is raised.
Several functions may be specified as a list but they have to depend on the same symbolic variables, for example, {f(x,y), g(y,x)}, but not {f(x,y), g(a,b)}. The functions will be plotted on the same graph using the same coordinate ranges.
If you have defined a function which accepts a number but does not accept an undefined variable, Plot3DS will fail to plot it. Use NFunction to overcome this difficulty.
Data files are created in a temporary directory /tmp/plot.tmp/ unless otherwise requested. File names and other information is printed if the Verbose option is switched on using V().
The current algorithm uses Newton-Cotes cubatures and some heuristics for error estimation (see The Yacas book of algorithms, Chapter 3, Section 1 ). The initial rectangular grid of xpoints+1*ypoints+1 points is refined within any rectangle where the integral of f(x,y) is not approximated to the given precision by the existing grid.
Default plotting range is -5:5 in both coordinates. A range can also be specified with a variable name, e.g. x= -5:5 (note the mandatory space separating "=" and "-"). The variable name x should be the same as that used in the function f(x,y). If ranges are not given with variable names, the first variable encountered in the function f(x,y) is associated with the first of the two ranges.
Options are of the form option=value. Currently supported option names are "points", "xpoints", "ypoints", "precision", "depth", "output", "filename", "xrange", "yrange", "zrange". Option values are either numbers or special unevaluated atoms such as data. If you need to use the names of these atoms in your script, strings can be used (e.g. output="gnuplot"). Several option/value pairs may be specified (the function Plot3DS has a variable number of arguments).
Other options may be supported in the future.
The current implementation can deal with a singularity within the plotting range only if the function f(x,y) returns Infinity, -Infinity or Undefined at the singularity. If the function f(x,y) generates a numerical error and fails at a singularity, Plot3DS will fail only if one of the grid points falls on the singularity. (All grid points are generated by bisection so in principle the endpoints and the xpoints, ypoints parameters could be chosen to avoid numerical singularities.)
The filename option is optional if using graphical backends, but can be used to specify the location of the created data file.
*WIN32
Same limitations as Plot2D.
In> Plot3DS(a*b^2) Out> True; In> V(Plot3DS(Sin(x)*Cos(y),x=0:20, y=0:20,depth=3)) CachedConstant: Info: constant Pi is being recalculated at precision 10 CachedConstant: Info: constant Pi is being recalculated at precision 11 Plot3DS: using 1699 points for function Sin(x)*Cos(y) Plot3DS: max. used 8 subdivisions for Sin(x)*Cos(y) Plot3DS'datafile: created file '/tmp/plot.tmp/data1' Out> True; |
XmlExplodeTag(xmltext) |
The following subset of XML syntax is supported currently:
The tag options take the form paramname="value".
If given an XML tag, XmlExplodeTag returns a structure of the form XmlTag(name,params,type). In the returned object, name is the (capitalized) tag name, params is an assoc list with the options (key fields capitalized), and type can be either "Open", "Close" or "OpenClose".
If given a plain text string, the same string is returned.
In> XmlExplodeTag("some plain text") Out> "some plain text"; In> XmlExplodeTag("<a name=\"blah blah\" align=\"left\">") Out> XmlTag("A",{{"ALIGN","left"}, {"NAME","blah blah"}},"Open"); In> XmlExplodeTag("</p>") Out> XmlTag("P",{},"Close"); In> XmlExplodeTag("<br/>") Out> XmlTag("BR",{},"OpenClose"); |
DefaultTokenizer() XmlTokenizer() CTokenizer() |
The Yacas environment currently supports some experimental tokenizers for various syntaxes. DefaultTokenizer switches to the tokenizer used for default Yacas syntax. XmlTokenizer switches to an XML syntax and CTokenizer to a C syntax. Note that setting the tokenizer is a global side effect. One typically needs to switch back to the default tokenizer when finished reading the special syntax.
Care needs to be taken when kernel errors are raised during a non-default tokenizer operation (as with any global change in the environment). Errors need to be caught with the TrapError function. The error handler code should re-instate the default tokenizer, or else the user will be unable to continue the session (everything a user types will be parsed using a non-default tokenizer).
When reading XML syntax, the supported formats are the same as those of XmlExplodeTag. The parser does not validate anything in the XML input. After an XML token has been read in, it can be converted into an Yacas expression with XmlExplodeTag. Note that when reading XML, any plain text between tags is returned as one token. Any malformed XML will be treated as plain text.
CTokenizer is an implementation of a C/C++ tokenizer. It is still work in progress.
In> [XmlTokenizer(); q:=ReadToken(); \ DefaultTokenizer();q;] <a>Out> <a>; |
Note that:
OMForm(expression) OMParse() |
In> str:=ToString()OMForm(2+Sin(a*3)) Out> "<OMOBJ> <OMA> <OMS cd="arith1" name="plus"/> <OMI>2</OMI> <OMA> <OMS cd="transc1" name="sin"/> <OMA> <OMS cd="arith1" name="times"/> <OMV name="a"/> <OMI>3</OMI> </OMA> </OMA> </OMA> </OMOBJ> "; In> FromString(str)OMParse() Out> 2+Sin(a*3); |
SetStringMid(index,substring,string) |
substring -- substring to store
string -- string to store substring in.
In> SetStringMid(3,"XY","abcdef") Out> "abXYef"; |
StringMid(index,length,string) |
length -- length of substring to get
string -- string to get substring from
In> StringMid(3,2,"abcdef") Out> "cd"; In> "abcdefg"[2 .. 4] Out> "bcd"; |
Atom("string") String(atom) |
"string" -- a string
String is the inverse of Atom: turns atom into "atom".
In> String(a) Out> "a"; In> Atom("a") Out> a; |
ConcatStrings(strings) |
In> ConcatStrings("a","b","c") Out> "abc"; |
LocalSymbols(var1, var2, ...) body |
body -- expression to execute
This is useful in cases where a guaranteed free variable is needed, for example, in the macro-like functions (For, While, etc.).
In> LocalSymbols(a,b)a+b Out> $a6+ $b6; |
PatchString(string) |
In> PatchString("Two plus three \ is <? Write(2+3); ?> "); Out> "Two plus three is 5 "; |
BernoulliDistribution(p) |
Numerical value of p must satisfy 0<p<1.
BinomialDistribution(p,n) |
n -- number of trials
Numerical value of p must satisfy 0<p<1. Numerical value of n must be a positive integer.
{tDistribution}(m) |
Let Y and Z be independent random variables, Y have the NormalDistribution(0,1), Z have ChiSquareDistribution(m). Then Y/Sqrt(Z/m) has tDistribution(m).
Numerical value of m must be positive integer.
PDF(dist,x) |
x -- a value of random variable
ChiSquareTest(observed,expected) ChiSquareTest(observed,expected,params) |
expected -- list of expected frequencies
params -- number of estimated parameters
The function returns a list of three local substitution rules. First of them contains the test statistic, the second contains the value of the parameters, and the last one contains the degrees of freedom.
The test statistic is distributed as ChiSquareDistribution.
GetYacasPID() |
Requires: a Unix shell.
In> GetYacasPID() Out> 26456; |
ShowPS(expr) |
Requires: a Unix shell, latex, dvips, gv or another Postscript viewer.
In> [ PSViewCommand := "ghostview"; \ ShowPS(x+2*Sin(x)); ] Expression exported as /tmp/yacas-tmp file-28802.tex Out> True; |
MakeFunctionPlugin("name", body) MakeFunctionPlugin() |
body -- expression, function of arguments, must evaluate to a function of some variables.
The second form of the function is a predicate that checks that the function plugin facility is supported. (It may not be available on all platforms.)
Requires: a Unix shell, a compiler named c++ with ELF .so support, Yacas headers in FindFile("")/include; current directory must be writable. Error messages will be printed otherwise.
The body expression must be a CForm()-exportable function of the arguments and may contain numerical constants. Pi is allowed and will be converted to floating-point.
All arguments and the return value of the function are assumed to be double precision real numbers. The result of passing a non-numerical argument will be an unevaluated expression.
The function creates the following files in subdirectory plugins.tmp/ of current directory:
double f1_plugin_cc(double x, double y) { return sin(x/y); } |
After creating these files, MakeFunctionPlugin() will:
If you call MakeFunctionPlugin() repeatedly to define a function with the same name, old files will be overwritten and old libraries will be unloaded with DllUnload().
If the numerical calculation does not return a number (for example, it might return the atom nan, "not a number", for some arguments), then the new function will return Undefined. This is the behavior of NFunction which is used to wrap the numerical routine.
In> MakeFunctionPlugin("f1", Sin(x/y)) Function f1(x,y) loaded from plugins.tmp/libf1_plugin_cc.so Out> True; In> f1(2,3) Out> 0.618369803069736989620253; In> f1(x,5) Out> f1(x,5); |
Version() |
In> Version() Out> "1.0.48rev3"; In> LessThan(Version(), "1.0.47") Out> False; In> GreaterThan(Version(), "1.0.47") Out> True; |
The last two calls show that the LessThan and GreaterThan functions can be used for comparing version numbers. This method is only guaranteed, however, if the version is always expressed in the form d.d.dd as above.
Vi(filename); Vi(functionname); |
functionname - name of a function to find for editing
It finds the function by scanning the *.def files that have been reported to the system. (Vi calls FindFunction for this.) If editing a function, the command will jump directly to the first occurrence of the name of the function in the file (usually the beginning of a definition of a function).
If you would like to use Vi() to actually edit the Yacas library source file where the function is defined, you need to start Yacas from the scripts/ directory in the development tree. In that case, FindFunction() will return the filename under that directory. Otherwise, FindFunction() will return a name in the systemwide installation directory (or directory specified in the --rootdir option).
In> Vi("yacasinit.ys") Out> True; In> Vi("Sum") Out> True; |
FilePathSeparator PlatformOS() OSVersion() |
The value of OSVersion() is normally determined when Yacas is compiled. It is usually the operating system name and version as reported by the config.guess script. However, it may be overridden at build time (on non-Unix systems, the script cannot be run and the value must be specified by hand).
The value of PlatformOS() is defined in the library (in osdep.rep/). Thus the library is able to override the platform-specific value. The scripts should use PlatformOS() to distinguish between broad classes of systems. The currently supported values are "Unix" and "Win32".
The constant FilePathSeparator is the string that separates directories in the file system tree. This is the forward slash "/" on Unix and the backslash "\" on Windows.
In> Check(StringMid(1, 5, OSVersion())="linux", \ "BAAA! I WANT LINUX!") Out> True; In> PlatformOS() Out> "Unix"; |
CopyFile("src","dest") DeleteFile("file", ...) DeleteDir("dir", ...) MakeDir("dir1", ...) MakeFilePath("dir1", "dir2", ..., "file") TemporaryDir() TemporaryFile() |
Absolute file paths or relative file paths can be given (the current directory is the directory where Yacas was started).
File and directory names may contain spaces, although the behavior on Windows platform may be incorrect due to its broken filesystem and command interpreter. File and directory names should not contain double quotes ("). (On Unix, double quotes may be escaped by a backslash.)
When operating on many files or directories at once, there may be errors associated with some files but not others. The functions return True only if all operations succeeded. Error messages from the OS are printed on the console as usual for SystemCall.
In> MakeFilePath("", "usr", "bin", "yacas") Out> "/usr/bin/yacas"; In> TemporaryDir() Out> "/tmp"; |
In> CopyFile("f1.txt", "f2.txt") Out> True; |
In> MakeDir(d:=MakeFilePath(TemporaryDir(), \ "subdir")) Out> True; In> d Out> "/tmp/subdir"; |
In> CopyFile("f2.txt", d) Out> True; |
In> MakeDir("a \\\"") Out> True; |
An unsuccessful attempt to delete a directory:
In> DeleteDir("C:\\WINDOWS") Out> False; |
SystemCallBg("command") |
Unlike the SystemCall function, the return status of the command is not available.
Error messages from the OS are printed on the console as usual for SystemCall.
In> SystemCallBg("mozilla") Out> True; |
To use the plugin, the plugin has to be loaded through:
Use("filescanner"); |
The file scanner plugin offers one principal new function; ScanFiles. The prototype for this function is:
ScanFiles(BaseDirectory,SubDirectory,CallFunction); |
The arguments:
The call-back function should accept three arguments: the base directory, the file name and a boolean specifying if the file is a sub-directory.
The full file name can be obtained by concatenating the file name to the base directory. If the file is a sub-directory, the file name can be used as the name of the sub-directory in subsequent recursive calls to ScanFiles.
For example, the following definition of the function tst can be used as a third argument to ScanFiles, in order to scan directories recursively, printing file names of files in the directories.
// File, print 10 # tst(_a,_b,False) <-- Echo("File: ",b) // Directory, scan recursively 20 # tst(_a,_b,True) <-- ScanFiles(a,b,"tst") |
Then, if the Yacas source is in /Users/ayalpink/yacas/, one can call:
ScanFiles("/Users/someone/yacas/","plugins","tst") |
The first lines of output (in Yacas version 1.0.55) is:
File: plugins/.cvsignore File: plugins/CVS/Entries File: plugins/CVS/Repository File: plugins/CVS/Root File: plugins/doc.txt |
Here the scan went into the CVS sub-directory. Appending these file names to the base directory, /Users/someone/yacas/, would give the full path to the file.
To use the plugin, the plugin has to be loaded through:
Use("pcre"); |
The pcre plugin offers two principal functions: PcreLexer and PcreNextToken. PcreLexer sets up and initializes the tokenizer to scan for a set of regular expressions. A call to PcreNextToken returns the result of the scan in the current file, starting from the current position.
PcreLexer does not interfere with normal reading of a file. When normal read calls are made, the default tokenizer is used. The tokenizer set up by PcreLexer is only used when PcreNextToken is called.
The syntax for PcreLexer is:
PcreLexer(tokens); |
The argument tokens is a list of token definitions. A token definition in turn is a list, with the first element a string containing the regular expression, and the second containing an atom that can describe the type of the token (for easy recognition later).
Calling PcreNextToken() will then return the first matching token from the current input.
The following example sets up the tokenizer to recognize either an integer, or a word consisting only of lowercase letters.
In> DllLoad("pcre") Out> True In> PcreLexer({{"[0-9]+",Integer},{"[a-z]+",Word}}) Out> True In> FromString("123abc")PcreNextToken() Out> {"123",Integer} In> FromString("===abc")PcreNextToken() Out> {"abc",Word} |
Function gsl'acosh(x), calls double gsl_acosh (double x)
Function gsl'asinh(x), calls double gsl_asinh (double x)
Function gsl'atanh(x), calls double gsl_atanh (double x)
Function gsl'coerce'double(x), calls double gsl_coerce_double (double x)
Function gsl'expm1(x), calls double gsl_expm1 (double x)
Function gsl'fdiv(x,y), calls double gsl_fdiv (double x, double y)
Function gsl'hypot(x,y), calls double gsl_hypot (double x, double y)
Function gsl'ldexp(x,e), calls double gsl_ldexp (double x, int e)
Function gsl'log1p(x), calls double gsl_log1p (double x)
Function gsl'max(a,b), calls double gsl_max (double a, double b)
Function gsl'min(a,b), calls double gsl_min (double a, double b)
Function gsl'pow'2(x), calls double gsl_pow_2 (double x)
Function gsl'pow'3(x), calls double gsl_pow_3 (double x)
Function gsl'pow'4(x), calls double gsl_pow_4 (double x)
Function gsl'pow'5(x), calls double gsl_pow_5 (double x)
Function gsl'pow'6(x), calls double gsl_pow_6 (double x)
Function gsl'pow'7(x), calls double gsl_pow_7 (double x)
Function gsl'pow'8(x), calls double gsl_pow_8 (double x)
Function gsl'pow'9(x), calls double gsl_pow_9 (double x)
Function gsl'pow'int(x,n), calls double gsl_pow_int (double x, int n)
Function gsl'ran'bernoulli'pdf(k,p), calls double gsl_ran_bernoulli_pdf (int k, double p)
Function gsl'ran'beta'pdf(x,a,b), calls double gsl_ran_beta_pdf (double x, double a, double b)
Function gsl'ran'binomial'pdf(k,p,n), calls double gsl_ran_binomial_pdf (int k, double p, int n)
Function gsl'ran'bivariate'gaussian'pdf(x,y,sigma_x,sigma_y,rho), calls double gsl_ran_bivariate_gaussian_pdf (double x, double y, double sigma_x, double sigma_y, double rho)
Function gsl'ran'cauchy'pdf(x,a), calls double gsl_ran_cauchy_pdf (double x, double a)
Function gsl'ran'chisq'pdf(x,nu), calls double gsl_ran_chisq_pdf (double x, double nu)
Function gsl'ran'erlang'pdf(x,a,n), calls double gsl_ran_erlang_pdf (double x, double a, double n)
Function gsl'ran'exponential'pdf(x,mu), calls double gsl_ran_exponential_pdf (double x, double mu)
Function gsl'ran'exppow'pdf(x,a,b), calls double gsl_ran_exppow_pdf (double x, double a, double b)
Function gsl'ran'fdist'pdf(x,nu1,nu2), calls double gsl_ran_fdist_pdf (double x, double nu1, double nu2)
Function gsl'ran'flat'pdf(x,a,b), calls double gsl_ran_flat_pdf (double x, double a, double b)
Function gsl'ran'gamma'pdf(x,a,b), calls double gsl_ran_gamma_pdf (double x, double a, double b)
Function gsl'ran'gaussian'pdf(x,sigma), calls double gsl_ran_gaussian_pdf (double x, double sigma)
Function gsl'ran'gaussian'tail'pdf(x,a,sigma), calls double gsl_ran_gaussian_tail_pdf (double x, double a, double sigma)
Function gsl'ran'geometric'pdf(k,p), calls double gsl_ran_geometric_pdf (int k, double p)
Function gsl'ran'gumbel1'pdf(x,a,b), calls double gsl_ran_gumbel1_pdf (double x, double a, double b)
Function gsl'ran'gumbel2'pdf(x,a,b), calls double gsl_ran_gumbel2_pdf (double x, double a, double b)
Function gsl'ran'hypergeometric'pdf(k,n1,n2,t), calls double gsl_ran_hypergeometric_pdf (int k, int n1, int n2, int t)
Function gsl'ran'landau'pdf(x), calls double gsl_ran_landau_pdf (double x)
Function gsl'ran'laplace'pdf(x,a), calls double gsl_ran_laplace_pdf (double x, double a)
Function gsl'ran'logarithmic'pdf(k,p), calls double gsl_ran_logarithmic_pdf (int k, double p)
Function gsl'ran'logistic'pdf(x,a), calls double gsl_ran_logistic_pdf (double x, double a)
Function gsl'ran'lognormal'pdf(x,zeta,sigma), calls double gsl_ran_lognormal_pdf (double x, double zeta, double sigma)
Function gsl'ran'negative'binomial'pdf(k,p,n), calls double gsl_ran_negative_binomial_pdf (int k, double p, double n)
Function gsl'ran'pareto'pdf(x,a,b), calls double gsl_ran_pareto_pdf (double x, double a, double b)
Function gsl'ran'pascal'pdf(k,p,n), calls double gsl_ran_pascal_pdf (int k, double p, int n)
Function gsl'ran'poisson'pdf(k,mu), calls double gsl_ran_poisson_pdf (int k, double mu)
Function gsl'ran'rayleigh'pdf(x,sigma), calls double gsl_ran_rayleigh_pdf (double x, double sigma)
Function gsl'ran'rayleigh'tail'pdf(x,a,sigma), calls double gsl_ran_rayleigh_tail_pdf (double x, double a, double sigma)
Function gsl'ran'tdist'pdf(x,nu), calls double gsl_ran_tdist_pdf (double x, double nu)
Function gsl'ran'ugaussian'pdf(x), calls double gsl_ran_ugaussian_pdf (double x)
Function gsl'ran'ugaussian'tail'pdf(x,a), calls double gsl_ran_ugaussian_tail_pdf (double x, double a)
Function gsl'ran'weibull'pdf(x,a,b), calls double gsl_ran_weibull_pdf (double x, double a, double b)
Function gsl'sf'airy'Ai(x,mode), calls double gsl_sf_airy_Ai (double x, int mode)
Function gsl'sf'airy'Ai'deriv(x,mode), calls double gsl_sf_airy_Ai_deriv (double x, int mode)
Function gsl'sf'airy'Ai'deriv'scaled(x,mode), calls double gsl_sf_airy_Ai_deriv_scaled (double x, int mode)
Function gsl'sf'airy'Ai'scaled(x,mode), calls double gsl_sf_airy_Ai_scaled (double x, int mode)
Function gsl'sf'airy'Bi(x,mode), calls double gsl_sf_airy_Bi (double x, int mode)
Function gsl'sf'airy'Bi'deriv(x,mode), calls double gsl_sf_airy_Bi_deriv (double x, int mode)
Function gsl'sf'airy'Bi'deriv'scaled(x,mode), calls double gsl_sf_airy_Bi_deriv_scaled (double x, int mode)
Function gsl'sf'airy'Bi'scaled(x,mode), calls double gsl_sf_airy_Bi_scaled (double x, int mode)
Function gsl'sf'airy'zero'Ai(s), calls double gsl_sf_airy_zero_Ai (int s)
Function gsl'sf'airy'zero'Ai'deriv(s), calls double gsl_sf_airy_zero_Ai_deriv (int s)
Function gsl'sf'airy'zero'Bi(s), calls double gsl_sf_airy_zero_Bi (int s)
Function gsl'sf'airy'zero'Bi'deriv(s), calls double gsl_sf_airy_zero_Bi_deriv (int s)
Function gsl'sf'angle'restrict'pos(theta), calls double gsl_sf_angle_restrict_pos (double theta)
Function gsl'sf'angle'restrict'symm(theta), calls double gsl_sf_angle_restrict_symm (double theta)
Function gsl'sf'atanint(x), calls double gsl_sf_atanint (double x)
Function gsl'sf'bessel'I0(x), calls double gsl_sf_bessel_I0 (double x)
Function gsl'sf'bessel'I0'scaled(x), calls double gsl_sf_bessel_I0_scaled (double x)
Function gsl'sf'bessel'i0'scaled(x), calls double gsl_sf_bessel_i0_scaled (double x)
Function gsl'sf'bessel'I1(x), calls double gsl_sf_bessel_I1 (double x)
Function gsl'sf'bessel'I1'scaled(x), calls double gsl_sf_bessel_I1_scaled (double x)
Function gsl'sf'bessel'i1'scaled(x), calls double gsl_sf_bessel_i1_scaled (double x)
Function gsl'sf'bessel'i2'scaled(x), calls double gsl_sf_bessel_i2_scaled (double x)
Function gsl'sf'bessel'il'scaled(l,x), calls double gsl_sf_bessel_il_scaled (int l, double x)
Function gsl'sf'bessel'In(n,x), calls double gsl_sf_bessel_In (int n, double x)
Function gsl'sf'bessel'Inu(nu,x), calls double gsl_sf_bessel_Inu (double nu, double x)
Function gsl'sf'bessel'Inu'scaled(nu,x), calls double gsl_sf_bessel_Inu_scaled (double nu, double x)
Function gsl'sf'bessel'In'scaled(n,x), calls double gsl_sf_bessel_In_scaled (int n, double x)
Function gsl'sf'bessel'J0(x), calls double gsl_sf_bessel_J0 (double x)
Function gsl'sf'bessel'j0(x), calls double gsl_sf_bessel_j0 (double x)
Function gsl'sf'bessel'J1(x), calls double gsl_sf_bessel_J1 (double x)
Function gsl'sf'bessel'j1(x), calls double gsl_sf_bessel_j1 (double x)
Function gsl'sf'bessel'j2(x), calls double gsl_sf_bessel_j2 (double x)
Function gsl'sf'bessel'jl(l,x), calls double gsl_sf_bessel_jl (int l, double x)
Function gsl'sf'bessel'Jn(n,x), calls double gsl_sf_bessel_Jn (int n, double x)
Function gsl'sf'bessel'Jnu(nu,x), calls double gsl_sf_bessel_Jnu (double nu, double x)
Function gsl'sf'bessel'K0(x), calls double gsl_sf_bessel_K0 (double x)
Function gsl'sf'bessel'K0'scaled(x), calls double gsl_sf_bessel_K0_scaled (double x)
Function gsl'sf'bessel'k0'scaled(x), calls double gsl_sf_bessel_k0_scaled (double x)
Function gsl'sf'bessel'K1(x), calls double gsl_sf_bessel_K1 (double x)
Function gsl'sf'bessel'K1'scaled(x), calls double gsl_sf_bessel_K1_scaled (double x)
Function gsl'sf'bessel'k1'scaled(x), calls double gsl_sf_bessel_k1_scaled (double x)
Function gsl'sf'bessel'k2'scaled(x), calls double gsl_sf_bessel_k2_scaled (double x)
Function gsl'sf'bessel'kl'scaled(l,x), calls double gsl_sf_bessel_kl_scaled (int l, double x)
Function gsl'sf'bessel'Kn(n,x), calls double gsl_sf_bessel_Kn (int n, double x)
Function gsl'sf'bessel'Knu(nu,x), calls double gsl_sf_bessel_Knu (double nu, double x)
Function gsl'sf'bessel'Knu'scaled(nu,x), calls double gsl_sf_bessel_Knu_scaled (double nu, double x)
Function gsl'sf'bessel'Kn'scaled(n,x), calls double gsl_sf_bessel_Kn_scaled (int n, double x)
Function gsl'sf'bessel'lnKnu(nu,x), calls double gsl_sf_bessel_lnKnu (double nu, double x)
Function gsl'sf'bessel'Y0(x), calls double gsl_sf_bessel_Y0 (double x)
Function gsl'sf'bessel'y0(x), calls double gsl_sf_bessel_y0 (double x)
Function gsl'sf'bessel'Y1(x), calls double gsl_sf_bessel_Y1 (double x)
Function gsl'sf'bessel'y1(x), calls double gsl_sf_bessel_y1 (double x)
Function gsl'sf'bessel'y2(x), calls double gsl_sf_bessel_y2 (double x)
Function gsl'sf'bessel'yl(l,x), calls double gsl_sf_bessel_yl (int l, double x)
Function gsl'sf'bessel'Yn(n,x), calls double gsl_sf_bessel_Yn (int n, double x)
Function gsl'sf'bessel'Ynu(nu,x), calls double gsl_sf_bessel_Ynu (double nu, double x)
Function gsl'sf'bessel'zero'J0(s), calls double gsl_sf_bessel_zero_J0 (int s)
Function gsl'sf'bessel'zero'J1(s), calls double gsl_sf_bessel_zero_J1 (int s)
Function gsl'sf'bessel'zero'Jnu(nu,s), calls double gsl_sf_bessel_zero_Jnu (double nu, int s)
Function gsl'sf'beta(a,b), calls double gsl_sf_beta (double a, double b)
Function gsl'sf'beta'inc(a,b,x), calls double gsl_sf_beta_inc (double a, double b, double x)
Function gsl'sf'Chi(x), calls double gsl_sf_Chi (double x)
Function gsl'sf'choose(n,m), calls double gsl_sf_choose (int n, int m)
Function gsl'sf'Ci(x), calls double gsl_sf_Ci (double x)
Function gsl'sf'clausen(x), calls double gsl_sf_clausen (double x)
Function gsl'sf'conicalP'0(lambda,x), calls double gsl_sf_conicalP_0 (double lambda, double x)
Function gsl'sf'conicalP'1(lambda,x), calls double gsl_sf_conicalP_1 (double lambda, double x)
Function gsl'sf'conicalP'cyl'reg(m,lambda,x), calls double gsl_sf_conicalP_cyl_reg (int m, double lambda, double x)
Function gsl'sf'conicalP'half(lambda,x), calls double gsl_sf_conicalP_half (double lambda, double x)
Function gsl'sf'conicalP'mhalf(lambda,x), calls double gsl_sf_conicalP_mhalf (double lambda, double x)
Function gsl'sf'conicalP'sph'reg(l,lambda,x), calls double gsl_sf_conicalP_sph_reg (int l, double lambda, double x)
Function gsl'sf'cos(x), calls double gsl_sf_cos (double x)
Function gsl'sf'dawson(x), calls double gsl_sf_dawson (double x)
Function gsl'sf'debye'1(x), calls double gsl_sf_debye_1 (double x)
Function gsl'sf'debye'2(x), calls double gsl_sf_debye_2 (double x)
Function gsl'sf'debye'3(x), calls double gsl_sf_debye_3 (double x)
Function gsl'sf'debye'4(x), calls double gsl_sf_debye_4 (double x)
Function gsl'sf'dilog(x), calls double gsl_sf_dilog (double x)
Function gsl'sf'doublefact(n), calls double gsl_sf_doublefact (int n)
Function gsl'sf'ellint'D(phi,k,n,mode), calls double gsl_sf_ellint_D (double phi, double k, double n, int mode)
Function gsl'sf'ellint'E(phi,k,mode), calls double gsl_sf_ellint_E (double phi, double k, int mode)
Function gsl'sf'ellint'Ecomp(k,mode), calls double gsl_sf_ellint_Ecomp (double k, int mode)
Function gsl'sf'ellint'F(phi,k,mode), calls double gsl_sf_ellint_F (double phi, double k, int mode)
Function gsl'sf'ellint'Kcomp(k,mode), calls double gsl_sf_ellint_Kcomp (double k, int mode)
Function gsl'sf'ellint'P(phi,k,n,mode), calls double gsl_sf_ellint_P (double phi, double k, double n, int mode)
Function gsl'sf'ellint'RC(x,y,mode), calls double gsl_sf_ellint_RC (double x, double y, int mode)
Function gsl'sf'ellint'RD(x,y,z,mode), calls double gsl_sf_ellint_RD (double x, double y, double z, int mode)
Function gsl'sf'ellint'RF(x,y,z,mode), calls double gsl_sf_ellint_RF (double x, double y, double z, int mode)
Function gsl'sf'ellint'RJ(x,y,z,p,mode), calls double gsl_sf_ellint_RJ (double x, double y, double z, double p, int mode)
Function gsl'sf'erf(x), calls double gsl_sf_erf (double x)
Function gsl'sf'erfc(x), calls double gsl_sf_erfc (double x)
Function gsl'sf'erf'Q(x), calls double gsl_sf_erf_Q (double x)
Function gsl'sf'erf'Z(x), calls double gsl_sf_erf_Z (double x)
Function gsl'sf'eta(s), calls double gsl_sf_eta (double s)
Function gsl'sf'eta'int(n), calls double gsl_sf_eta_int (int n)
Function gsl'sf'exp(x), calls double gsl_sf_exp (double x)
Function gsl'sf'expint'3(x), calls double gsl_sf_expint_3 (double x)
Function gsl'sf'expint'E1(x), calls double gsl_sf_expint_E1 (double x)
Function gsl'sf'expint'E1'scaled(x), calls double gsl_sf_expint_E1_scaled (double x)
Function gsl'sf'expint'E2(x), calls double gsl_sf_expint_E2 (double x)
Function gsl'sf'expint'E2'scaled(x), calls double gsl_sf_expint_E2_scaled (double x)
Function gsl'sf'expint'Ei(x), calls double gsl_sf_expint_Ei (double x)
Function gsl'sf'expint'Ei'scaled(x), calls double gsl_sf_expint_Ei_scaled (double x)
Function gsl'sf'expm1(x), calls double gsl_sf_expm1 (double x)
Function gsl'sf'exprel(x), calls double gsl_sf_exprel (double x)
Function gsl'sf'exprel'2(x), calls double gsl_sf_exprel_2 (double x)
Function gsl'sf'exprel'n(n,x), calls double gsl_sf_exprel_n (int n, double x)
Function gsl'sf'exp'mult(x,y), calls double gsl_sf_exp_mult (double x, double y)
Function gsl'sf'fact(n), calls double gsl_sf_fact (int n)
Function gsl'sf'fermi'dirac'0(x), calls double gsl_sf_fermi_dirac_0 (double x)
Function gsl'sf'fermi'dirac'1(x), calls double gsl_sf_fermi_dirac_1 (double x)
Function gsl'sf'fermi'dirac'2(x), calls double gsl_sf_fermi_dirac_2 (double x)
Function gsl'sf'fermi'dirac'3half(x), calls double gsl_sf_fermi_dirac_3half (double x)
Function gsl'sf'fermi'dirac'half(x), calls double gsl_sf_fermi_dirac_half (double x)
Function gsl'sf'fermi'dirac'inc'0(x,b), calls double gsl_sf_fermi_dirac_inc_0 (double x, double b)
Function gsl'sf'fermi'dirac'int(j,x), calls double gsl_sf_fermi_dirac_int (int j, double x)
Function gsl'sf'fermi'dirac'm1(x), calls double gsl_sf_fermi_dirac_m1 (double x)
Function gsl'sf'fermi'dirac'mhalf(x), calls double gsl_sf_fermi_dirac_mhalf (double x)
Function gsl'sf'gamma(x), calls double gsl_sf_gamma (double x)
Function gsl'sf'gammainv(x), calls double gsl_sf_gammainv (double x)
Function gsl'sf'gammastar(x), calls double gsl_sf_gammastar (double x)
Function gsl'sf'gamma'inc(a,x), calls double gsl_sf_gamma_inc (double a, double x)
Function gsl'sf'gamma'inc'P(a,x), calls double gsl_sf_gamma_inc_P (double a, double x)
Function gsl'sf'gamma'inc'Q(a,x), calls double gsl_sf_gamma_inc_Q (double a, double x)
Function gsl'sf'gegenpoly'1(lambda,x), calls double gsl_sf_gegenpoly_1 (double lambda, double x)
Function gsl'sf'gegenpoly'2(lambda,x), calls double gsl_sf_gegenpoly_2 (double lambda, double x)
Function gsl'sf'gegenpoly'3(lambda,x), calls double gsl_sf_gegenpoly_3 (double lambda, double x)
Function gsl'sf'gegenpoly'n(n,lambda,x), calls double gsl_sf_gegenpoly_n (int n, double lambda, double x)
Function gsl'sf'hazard(x), calls double gsl_sf_hazard (double x)
Function gsl'sf'hydrogenicR(n,l,Z,r), calls double gsl_sf_hydrogenicR (int n, int l, double Z, double r)
Function gsl'sf'hydrogenicR'1(Z,r), calls double gsl_sf_hydrogenicR_1 (double Z, double r)
Function gsl'sf'hyperg'0F1(c,x), calls double gsl_sf_hyperg_0F1 (double c, double x)
Function gsl'sf'hyperg'1F1(a,b,x), calls double gsl_sf_hyperg_1F1 (double a, double b, double x)
Function gsl'sf'hyperg'1F1'int(m,n,x), calls double gsl_sf_hyperg_1F1_int (int m, int n, double x)
Function gsl'sf'hyperg'2F0(a,b,x), calls double gsl_sf_hyperg_2F0 (double a, double b, double x)
Function gsl'sf'hyperg'2F1(a,b,c,x), calls double gsl_sf_hyperg_2F1 (double a, double b, double c, double x)
Function gsl'sf'hyperg'2F1'conj(aR,aI,c,x), calls double gsl_sf_hyperg_2F1_conj (double aR, double aI, double c, double x)
Function gsl'sf'hyperg'2F1'conj'renorm(aR,aI,c,x), calls double gsl_sf_hyperg_2F1_conj_renorm (double aR, double aI, double c, double x)
Function gsl'sf'hyperg'2F1'renorm(a,b,c,x), calls double gsl_sf_hyperg_2F1_renorm (double a, double b, double c, double x)
Function gsl'sf'hyperg'U(a,b,x), calls double gsl_sf_hyperg_U (double a, double b, double x)
Function gsl'sf'hyperg'U'int(m,n,x), calls double gsl_sf_hyperg_U_int (int m, int n, double x)
Function gsl'sf'hypot(x,y), calls double gsl_sf_hypot (double x, double y)
Function gsl'sf'hzeta(s,q), calls double gsl_sf_hzeta (double s, double q)
Function gsl'sf'laguerre'1(a,x), calls double gsl_sf_laguerre_1 (double a, double x)
Function gsl'sf'laguerre'2(a,x), calls double gsl_sf_laguerre_2 (double a, double x)
Function gsl'sf'laguerre'3(a,x), calls double gsl_sf_laguerre_3 (double a, double x)
Function gsl'sf'laguerre'n(n,a,x), calls double gsl_sf_laguerre_n (int n, double a, double x)
Function gsl'sf'lambert'W0(x), calls double gsl_sf_lambert_W0 (double x)
Function gsl'sf'lambert'Wm1(x), calls double gsl_sf_lambert_Wm1 (double x)
Function gsl'sf'legendre'H3d(l,lambda,eta), calls double gsl_sf_legendre_H3d (int l, double lambda, double eta)
Function gsl'sf'legendre'H3d'0(lambda,eta), calls double gsl_sf_legendre_H3d_0 (double lambda, double eta)
Function gsl'sf'legendre'H3d'1(lambda,eta), calls double gsl_sf_legendre_H3d_1 (double lambda, double eta)
Function gsl'sf'legendre'P1(x), calls double gsl_sf_legendre_P1 (double x)
Function gsl'sf'legendre'P2(x), calls double gsl_sf_legendre_P2 (double x)
Function gsl'sf'legendre'P3(x), calls double gsl_sf_legendre_P3 (double x)
Function gsl'sf'legendre'Pl(l,x), calls double gsl_sf_legendre_Pl (int l, double x)
Function gsl'sf'legendre'Plm(l,m,x), calls double gsl_sf_legendre_Plm (int l, int m, double x)
Function gsl'sf'legendre'Q0(x), calls double gsl_sf_legendre_Q0 (double x)
Function gsl'sf'legendre'Q1(x), calls double gsl_sf_legendre_Q1 (double x)
Function gsl'sf'legendre'Ql(l,x), calls double gsl_sf_legendre_Ql (int l, double x)
Function gsl'sf'legendre'sphPlm(l,m,x), calls double gsl_sf_legendre_sphPlm (int l, int m, double x)
Function gsl'sf'lnbeta(a,b), calls double gsl_sf_lnbeta (double a, double b)
Function gsl'sf'lnchoose(n,m), calls double gsl_sf_lnchoose (int n, int m)
Function gsl'sf'lncosh(x), calls double gsl_sf_lncosh (double x)
Function gsl'sf'lndoublefact(n), calls double gsl_sf_lndoublefact (int n)
Function gsl'sf'lnfact(n), calls double gsl_sf_lnfact (int n)
Function gsl'sf'lngamma(x), calls double gsl_sf_lngamma (double x)
Function gsl'sf'lnpoch(a,x), calls double gsl_sf_lnpoch (double a, double x)
Function gsl'sf'lnsinh(x), calls double gsl_sf_lnsinh (double x)
Function gsl'sf'log(x), calls double gsl_sf_log (double x)
Function gsl'sf'log'1plusx(x), calls double gsl_sf_log_1plusx (double x)
Function gsl'sf'log'1plusx'mx(x), calls double gsl_sf_log_1plusx_mx (double x)
Function gsl'sf'log'abs(x), calls double gsl_sf_log_abs (double x)
Function gsl'sf'log'erfc(x), calls double gsl_sf_log_erfc (double x)
Function gsl'sf'multiply(x,y), calls double gsl_sf_multiply (double x, double y)
Function gsl'sf'poch(a,x), calls double gsl_sf_poch (double a, double x)
Function gsl'sf'pochrel(a,x), calls double gsl_sf_pochrel (double a, double x)
Function gsl'sf'pow'int(x,n), calls double gsl_sf_pow_int (double x, int n)
Function gsl'sf'psi(x), calls double gsl_sf_psi (double x)
Function gsl'sf'psi'1(x), calls double gsl_sf_psi_1 (double x)
Function gsl'sf'psi'1piy(y), calls double gsl_sf_psi_1piy (double y)
Function gsl'sf'psi'1'int(n), calls double gsl_sf_psi_1_int (int n)
Function gsl'sf'psi'int(n), calls double gsl_sf_psi_int (int n)
Function gsl'sf'psi'n(n,x), calls double gsl_sf_psi_n (int n, double x)
Function gsl'sf'Shi(x), calls double gsl_sf_Shi (double x)
Function gsl'sf'Si(x), calls double gsl_sf_Si (double x)
Function gsl'sf'sin(x), calls double gsl_sf_sin (double x)
Function gsl'sf'sinc(x), calls double gsl_sf_sinc (double x)
Function gsl'sf'synchrotron'1(x), calls double gsl_sf_synchrotron_1 (double x)
Function gsl'sf'synchrotron'2(x), calls double gsl_sf_synchrotron_2 (double x)
Function gsl'sf'taylorcoeff(n,x), calls double gsl_sf_taylorcoeff (int n, double x)
Function gsl'sf'transport'2(x), calls double gsl_sf_transport_2 (double x)
Function gsl'sf'transport'3(x), calls double gsl_sf_transport_3 (double x)
Function gsl'sf'transport'4(x), calls double gsl_sf_transport_4 (double x)
Function gsl'sf'transport'5(x), calls double gsl_sf_transport_5 (double x)
Function gsl'sf'zeta(s), calls double gsl_sf_zeta (double s)
Function gsl'sf'zetam1(s), calls double gsl_sf_zetam1 (double s)
Function gsl'sf'zetam1'int(s), calls double gsl_sf_zetam1_int (int s)
Function gsl'sf'zeta'int(n), calls double gsl_sf_zeta_int (int n)
Function gsl'fcmp(x1,x2,epsilon), calls int gsl_fcmp (double x1, double x2, double epsilon)
Function gsl'finite(x), calls int gsl_finite (double x)
Function gsl'isinf(x), calls int gsl_isinf (double x)
Function gsl'isnan(x), calls int gsl_isnan (double x)
Function gsl'sf'legendre'array'size(lmax,m), calls int gsl_sf_legendre_array_size (int lmax, int m)
This is an example mini-API.
Function AddTwoIntegers(arg1,arg2), calls int add_integers (int arg1, int arg2)
Function AddTwoDoubles(x,y), calls double add_doubles (double x, double y)
Declared struct Bla*
Function CreateBla(arg1,arg2), calls Bla* CreateBla (int arg1, int arg2)
Function BlaSetA(arg1,arg2), calls void BlaSetA (Bla* arg1, int arg2)
Function BlaGetA(arg1), calls int BlaGetA (Bla* arg1)
Constant GL_TRUE refers to the library name GL_TRUE
Constant GL_LINES refers to the library name GL_LINES
Constant GL_POINTS refers to the library name GL_POINTS
Constant GL_LINE_STRIP refers to the library name GL_LINE_STRIP
Constant GL_LINE_LOOP refers to the library name GL_LINE_LOOP
Constant GL_TRIANGLES refers to the library name GL_TRIANGLES
Constant GL_TRIANGLE_STRIP refers to the library name GL_TRIANGLE_STRIP
Constant GL_TRIANGLE_FAN refers to the library name GL_TRIANGLE_FAN
Constant GL_QUADS refers to the library name GL_QUADS
Constant GL_QUAD_STRIP refers to the library name GL_QUAD_STRIP
Constant GL_POLYGON refers to the library name GL_POLYGON
Constant GL_EDGE_FLAG refers to the library name GL_EDGE_FLAG
Constant GL_CURRENT_BIT refers to the library name GL_CURRENT_BIT
Constant GL_POINT_BIT refers to the library name GL_POINT_BIT
Constant GL_LINE_BIT refers to the library name GL_LINE_BIT
Constant GL_POLYGON_BIT refers to the library name GL_POLYGON_BIT
Constant GL_POLYGON_STIPPLE_BIT refers to the library name GL_POLYGON_STIPPLE_BIT
Constant GL_PIXEL_MODE_BIT refers to the library name GL_PIXEL_MODE_BIT
Constant GL_LIGHTING_BIT refers to the library name GL_LIGHTING_BIT
Constant GL_FOG_BIT refers to the library name GL_FOG_BIT
Constant GL_DEPTH_BUFFER_BIT refers to the library name GL_DEPTH_BUFFER_BIT
Constant GL_ACCUM_BUFFER_BIT refers to the library name GL_ACCUM_BUFFER_BIT
Constant GL_STENCIL_BUFFER_BIT refers to the library name GL_STENCIL_BUFFER_BIT
Constant GL_VIEWPORT_BIT refers to the library name GL_VIEWPORT_BIT
Constant GL_TRANSFORM_BIT refers to the library name GL_TRANSFORM_BIT
Constant GL_ENABLE_BIT refers to the library name GL_ENABLE_BIT
Constant GL_COLOR_BUFFER_BIT refers to the library name GL_COLOR_BUFFER_BIT
Constant GL_HINT_BIT refers to the library name GL_HINT_BIT
Constant GL_EVAL_BIT refers to the library name GL_EVAL_BIT
Constant GL_LIST_BIT refers to the library name GL_LIST_BIT
Constant GL_TEXTURE_BIT refers to the library name GL_TEXTURE_BIT
Constant GL_SCISSOR_BIT refers to the library name GL_SCISSOR_BIT
Constant GL_ALL_ATTRIB_BITS refers to the library name GL_ALL_ATTRIB_BITS
Constant GL_MATRIX_MODE refers to the library name GL_MATRIX_MODE
Constant GL_MODELVIEW refers to the library name GL_MODELVIEW
Constant GL_PROJECTION refers to the library name GL_PROJECTION
Constant GL_TEXTURE refers to the library name GL_TEXTURE
Function glBegin(arg1), calls void glBegin (int arg1)
Function glVertex3d(x,y,z), calls void glVertex3d (double x, double y, double z)
Function glEnd(), calls void glEnd ()
Function glClearColor(red,green,blue,alpha), calls void glClearColor (double red, double green, double blue, double alpha)
Function glClear(clear_flags), calls void glClear (int clear_flags)
Function glColor4d(arg1,arg2,arg3,arg4), calls void glColor4d (double arg1, double arg2, double arg3, double arg4)
Function glFrontFace(mode), calls void glFrontFace (int mode)
Function glPointSize(size), calls void glPointSize (double size)
Function glLineWidth(width), calls void glLineWidth (double width)
Function glEnable(cap), calls void glEnable (int cap)
Function glDisable(cap), calls void glDisable (int cap)
Function glPushMatrix(), calls void glPushMatrix ()
Function glPopMatrix(), calls void glPopMatrix ()
Function glLoadIdentity(), calls void glLoadIdentity ()
Function glRotated(angle,x,y,z), calls void glRotated (double angle, double x, double y, double z)
Function glScaled(x,y,z), calls void glScaled (double x, double y, double z)
Function glTranslated(x,y,z), calls void glTranslated (double x, double y, double z)
Function glNormal3d(nx,ny,nz), calls void glNormal3d (double nx, double ny, double nz)
Function glMatrixMode(mode), calls void glMatrixMode (int mode)
Function glOrtho(left,right,bottom,top,near_val,far_val), calls void glOrtho (double left, double right, double bottom, double top, double near_val, double far_val)
Function glFrustum(left,right,bottom,top,near_val,far_val), calls void glFrustum (double left, double right, double bottom, double top, double near_val, double far_val)
Function glViewport(x,y,width,height), calls void glViewport (int x, int y, int width, int height)
Constant GLUT_LEFT_BUTTON refers to the library name GLUT_LEFT_BUTTON
Constant GLUT_MIDDLE_BUTTON refers to the library name GLUT_MIDDLE_BUTTON
Constant GLUT_RIGHT_BUTTON refers to the library name GLUT_RIGHT_BUTTON
Constant GLUT_DOWN refers to the library name GLUT_DOWN
Constant GLUT_UP refers to the library name GLUT_UP
Function GlutMainLoop(window_title,window_width,window_height), calls void GlutMainLoop (input_string window_title, int window_width, int window_height)
Function GlutViewWidth(), calls int GlutViewWidth ()
Function GlutViewHeight(), calls int GlutViewHeight ()
Function GlutEnableAnimation(), calls void GlutEnableAnimation ()
Function GlutDisableAnimation(), calls void GlutDisableAnimation ()
Function glutPostRedisplay(), calls void glutPostRedisplay ()
Function GlutGetElapsedTime(), calls int GlutGetElapsedTime ()
59 Temple Place, Suite 330 Boston, MA, 02111-1307 USA |
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
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.
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.
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.
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. (For example, 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.
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.
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 ``Transparent'' copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and 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 has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is not ``Transparent'' is called ``Opaque''.
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 designed for human modification. Opaque formats include PostScript, PDF, 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 produced by some word processors for output purposes only.
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.
You may also lend copies, under the same conditions stated above, and you may publicly display copies.
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.
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 publicly-accessible computer-network location containing a complete Transparent copy of the Document, free of added material, which the general network-using public has access to download anonymously at no charge using public-standard network protocols. 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.
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.
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.
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.
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.
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.
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.
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.''
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.
If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one quarter of the entire aggregate, the Document's Cover Texts may be placed on covers that surround only the Document within the aggregate. Otherwise they must appear on covers around the whole aggregate.
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.
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.1 or any later version published by the Free Software Foundation; with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. A copy of the license is included in the section entitled ``GNU Free Documentation License''. |
If you have no Invariant Sections, write ``with no Invariant Sections'' instead of saying which ones are invariant. If you have no Front-Cover Texts, write ``no Front-Cover Texts'' instead of ``Front-Cover Texts being LIST''; likewise for Back-Cover Texts.
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.
/* comment */ // comment |
a+b; // get result a + /* add them */ b; |
Prog(statement1, statement2, ...) [ statement1; statement2; ... ] |
Prog(a,b); is the same as typing [a;b;]; and is very useful for writing out function bodies. The [ ... ] construct is a syntactically nicer version of the Prog call; it is converted into Prog(...) during the parsing stage.
Bodied("op", precedence) Infix("op") Infix("op", precedence) Postfix("op") Postfix("op", precedence) Prefix("op") Prefix("op", precedence) |
precedence -- nonnegative integer (evaluated)
"Bodied" functions have all arguments except the first one inside parentheses and the last argument outside, for example:
For(pre, condition, post) statement; |
D(x) Sin(x)+Cos(x) |
"Infix" functions must have two arguments and are syntactically placed between their arguments. Names of infix functions can be arbitrary, although for reasons of readability they are usually made of non-alphabetic characters.
"Prefix" functions must have one argument and are syntactically placed before their argument. "Postfix" functions must have one argument and are syntactically placed after their argument.
Function name can be any string but meaningful usage and readability would require it to be either made up entirely of letters or entirely of non-letter characters (such as "+", ":" etc.). Precedence is optional (will be set to 0 by default).
In> YY x := x+1; CommandLine(1) : Error parsing expression In> Prefix("YY", 2) Out> True; In> YY x := x+1; Out> True; In> YY YY 2*3 Out> 12; In> Infix("##", 5) Out> True; In> a ## b ## c Out> a##b##c; |
Note that, due to a current parser limitation, a function atom that is declared prefix cannot be used by itself as an argument.
In> YY CommandLine(1) : Error parsing expression |
IsBodied("op") IsInfix("op") IsPostfix("op") IsPrefix("op") |
In> IsInfix("+"); Out> True; In> IsBodied("While"); Out> True; In> IsBodied("Sin"); Out> False; In> IsPostfix("!"); Out> True; |
OpPrecedence("op") OpLeftPrecedence("op") OpRightPrecedence("op") |
For infix operators, right precedence can differ from left precedence. Bodied functions and prefix operators cannot have left precedence, while postfix operators cannot have right precedence; for these operators, there is only one value of precedence.
In> OpPrecedence("+") Out> 6; In> OpLeftPrecedence("!") Out> 0; |
RightAssociative("op") |
RightAssociative("*") |
LeftPrecedence("op",precedence) RightPrecedence("op",precedence) |
precedence -- nonnegative integer
This functionality was required in order to display expressions like a-(b-c) correctly. Thus, a+b+c is the same as a+(b+c), but a-(b-c) is not the same as a-b-c.
Note that the left and right precedence of an infix operator does not affect the way Yacas interprets expressions typed by the user. You cannot make Yacas parse a-b-c as a-(b-c) unless you declare the operator "-" to be right-associative.
RuleBase(name,params) |
params -- list of arguments to function
In the context of the transformation rule declaration facilities this is a useful function in that it allows the stating of argument names that can he used with HoldArg.
Functions can be overloaded: the same function can be defined with different number of arguments.
RuleBaseListed("name", params) |
params -- list of arguments to function
A function defined using RuleBaseListed will appear to have the arity equal to the number of parameters in the param list, and it can accept any number of arguments greater or equal than that. As a consequence, it will be impossible to define a new function with the same name and with a greater arity.
The function body will know that the function is passed more arguments than the length of the param list, because the last argument will then be a list. The rest then works like a RuleBase-defined function with a fixed number of arguments. Transformation rules can be defined for the new function as usual.
RuleBaseListed("f",{a,b,c}) 10 # f(_a,_b,{_c,_d}) <-- Echo({"four args",a,b,c,d}); 20 # f(_a,_b,c_IsList) <-- Echo({"more than four args",a,b,c}); 30 # f(_a,_b,_c) <-- Echo({"three args",a,b,c}); |
In> f(A) Out> f(A); In> f(A,B) Out> f(A,B); In> f(A,B,C) three args A B C Out> True; In> f(A,B,C,D) four args A B C D Out> True; In> f(A,B,C,D,E) more than four args A B {C,D,E} Out> True; In> f(A,B,C,D,E,E) more than four args A B {C,D,E,E} Out> True; |
The function f now appears to occupy all arities greater than 3:
In> RuleBase("f", {x,y,z,t}); CommandLine(1) : Rule base with this arity already defined |
Rule("operator", arity, precedence, predicate) body |
arity, precedence -- integers
predicate -- function returning boolean
body -- expression, body of rule
The arity for a rules database equals the number of arguments. Different rules data bases can be built for functions with the same name but with a different number of arguments.
Rules with a low precedence value will be tried before rules with a high value, so a rule with precedence 0 will be tried before a rule with precedence 1.
HoldArg("operator",parameter) |
parameter -- atom, symbolic name of parameter
The parameter must be an atom from the list of symbolic arguments used when calling RuleBase.
Retract("function",arity) |
arity -- positive integer
Assignment := of a function does this to the function being (re)defined.
UnFence("operator",arity) |
arity -- positive integers
The standard library functions For and ForEach use UnFence.
HoldArgNr("function", arity, argNum) |
arity, argNum -- positive integers
RuleBaseArgList("operator", arity) |
arity -- integer
Make sure that the arguments of Macro... commands evaluate to expressions that would normally be used in the non-macro versions!
`(expression) |
To invoke this functionality, a backquote ` needs to be placed in front of an expression. Parentheses around the expression are needed because the backquote binds tighter than other operators.
The expression should contain some variables (assigned atoms) with the special prefix operator @. Variables prefixed by @ will be evaluated even if they are inside function arguments that are normally not evaluated (e.g. functions declared with HoldArg). If the @var pair is in place of a function name, e.g. "@f(x)", then at the first stage of evaluation the function name itself is replaced, not the return value of the function (see example); so at the second stage of evaluation, a new function may be called.
One way to view backquoting is to view it as a parametric expression generator. @var pairs get substituted with the value of the variable var even in contexts where nothing would be evaluated. This effect can be also achieved using UnList and Hold but the resulting code is much more difficult to read and maintain.
This operation is relatively slow since a new expression is built before it is evaluated, but nonetheless backquoting is a powerful mechanism that sometimes allows to greatly simplify code.
In> Decl(f1,f2) := \ In> `(@f1(x_IsNumber) <-- N(@f2(x))); Out> True; In> Decl(nSin,Sin) Out> True; In> Sin(1) Out> Sin(1); In> nSin(1) Out> 0.8414709848; |
This example assigns the expression func(value) to variable var. Normally the first argument of Set would be unevaluated.
In> SetF(var,func,value) := \ In> `(Set(@var,@func(@value))); Out> True; In> SetF(a,Sin,x) Out> True; In> a Out> Sin(x); |
DefMacroRuleBase(name,params) |
params -- list of arguments
With the usual functions, the evaluation model is that of the applicative-order model of substitution, meaning that first the arguments are evaluated, and then the function is applied to the result of evaluating these arguments. The function is entered, and the code inside the function can not access local variables outside of its own local variables.
With macros, the evaluation model is that of the normal-order model of substitution, meaning that all occurrences of variables in an expression are first substituted into the body of the macro, and only then is the resulting expression evaluated in its calling environment. This is important, because then in principle a macro body can access the local variables from the calling environment, whereas functions can not do that.
As an example, suppose there is a function square, which squares its argument, and a function add, which adds its arguments. Suppose the definitions of these functions are:
add(x,y) <-- x+y; |
square(x) <-- x*x; |
add(square(2),square(3)) |
add(4,9) |
In contrast, when add is a macro, the arguments to add are first expanded. So
add(square(2),square(3)) |
square(2) + square(3) |
Macros are useful for customizing syntax, and compilers can potentially greatly optimize macros, as they can be inlined in the calling environment, and optimized accordingly.
There are disadvantages, however. In interpreted mode, macros are slower, as the requirement for substitution means that a new expression to be evaluated has to be created on the fly. Also, when one of the parameters to the macro occur more than once in the body of the macro, it is evaluated multiple times.
When defining transformation rules for macros, the variables to be substituted need to be preceded by the @ operator, similar to the back-quoting mechanism. Apart from that, the two are similar, and all transformation rules can also be applied to macros.
Macros can co-exist with functions with the same name but different arity. For instance, one can have a function foo(a,b) with two arguments, and a macro foo(a,b,c) with three arguments.
In> DefMacroRuleBase("myfor",{init,pred,inc,body}) Out> True; In> myfor(_init,_pred,_inc,_body)<--[@init;While(@pred)[@body;@inc;];True;]; Out> True; In> a:=10 Out> 10; In> myfor(i:=1,i<10,i++,Echo(a*i)) 10 20 30 40 50 60 70 80 90 Out> True; In> i Out> 10; |
DefMacroRuleBaseListed("name", params) |
params -- list of arguments to function
SetExtraInfo(expr,tag) GetExtraInfo(expr) |
tag -- tag information (any other expression)
The function SetExtraInfo returns the tagged expression, leaving the original expression alone. This means there is a common pitfall: be sure to assign the returned value to a variable, or the tagged expression is lost when the temporary object is destroyed.
The original expression is left unmodified, and the tagged expression returned, in order to keep the atomic objects small. To tag an object, a new type of object is created from the old object, with one added property (the tag). The tag can be any expression whatsoever.
The function GetExtraInfo(x) retrieves this tag expression from an object x. If an object has no tag, it looks the same as if it had a tag with value False.
No part of the Yacas core uses tags in a way that is visible to the outside world, so for specific purposes a programmer can devise a format to use for tag information. Association lists (hashes) are a natural fit for this, although it is not required and a tag can be any object (except the atom False because it is indistinguishable from having no tag information). Using association lists is highly advised since it is most likely to be the format used by other parts of the library, and one needs to avoid clashes with other library code. Typically, an object will either have no tag or a tag which is an associative list (perhaps empty). A script that uses tagged objects will check whether an object has a tag and if so, will add or modify certain entries of the association list, preserving any other tag information.
Note that FlatCopy currently does not copy the tag information (see examples).
In> a:=2*b Out> 2*b; In> a:=SetExtraInfo(a,{{"type","integer"}}) Out> 2*b; In> a Out> 2*b; In> GetExtraInfo(a) Out> {{"type","integer"}}; In> GetExtraInfo(a)["type"] Out> "integer"; In> c:=a Out> 2*b; In> GetExtraInfo(c) Out> {{"type","integer"}}; In> c Out> 2*b; In> d:=FlatCopy(a); Out> 2*b; In> GetExtraInfo(d) Out> False; |
GarbageCollect() |
Reference counting refers to bookkeeping where in each object a counter is held, keeping track of the number of parts in the system using that object. When this count drops to zero, the object is automatically removed. Reference counting is not the fastest way of doing garbage collection, but it can be implemented in a very clean way with very little code.
Among the most important objects that are not reference counted are the strings. GarbageCollect collects these and disposes of them when they are not used any more.
GarbageCollect is useful when doing a lot of text processing, to clean up the text buffers. It is not highly needed, but it keeps memory use low.
FindFunction(function) |
In> FindFunction("Sum") Out> "sums.rep/code.ys"; In> FindFunction("Integrate") Out> "integrate.rep/code.ys"; |
Secure(body) |
MultiplyNum(x,y) MultiplyNum(x,y,z,...) MultiplyNum({x,y,z,...}) |
The function accepts any number of arguments (not less than two) or a list of numbers. The result is always a floating-point number (even if Numeric is not set).
CachedConstant(cache, Cname, Cfunc) |
Cname -- atom, name of the constant
Cfunc -- expression that evaluates the constant
The call to CachedConstant defines a new function named Cname() that returns the value of the constant at given precision. If the precision is increased, the value will be recalculated as necessary, otherwise calling Cname() will take very little time.
The parameter Cfunc must be an expression that can be evaluated and returns the value of the desired constant at the current precision. (Most arbitrary-precision mathematical functions do this by default.)
The associative list cache contains elements of the form {Cname, prec, value}, as illustrated in the example. If this list does not exist, it will be created.
This mechanism is currently used by N() to precompute the values of Pi and gamma. The name of the cache for N() is CacheOfConstantsN. The code in the function N() assigns unevaluated calls to Pi() and gamma() to the atoms Pi and gamma and declares them LazyGlobal. The result is that the constants will be recalculated only when they are used in the expression under N(). In other words, the code in N() does the equivalent of
Pi := Hold(Pi()); gamma := Hold(gamma()); LazyGlobal(Pi); LazyGlobal(gamma); |
In> CachedConstant( my'cache, Ln2, LnNum(2) ) Out> 0.6931471806; In> Ln2 Out> Ln2; In> Ln2() Out> 0.6931471806; In> [ Precision(20); V( Ln2() ); ] CachedConstant: Info: constant Ln2 is being recalculated at precision 20 Out> 0.69314718055994530942; In> my'cache Out> {{"Ln2",20,0.69314718055994530942}}; |
NewtonNum(func, x0, prec0, order) NewtonNum(func, x0, prec0) NewtonNum(func, x0) |
x0 -- initial value (must be close enough to the root)
prec0 -- initial precision (at least 4, default 5)
order -- convergence order (typically 2 or 3, default 2)
NewtonNum will iterate the given function starting from the initial value, until the sequence converges within current precision. Initially, up to 5 iterations at the initial precision prec0 is performed (the low precision is set for speed). The initial value x0 must be close enough to the root so that the initial iterations converge. If the sequence does not produce even a single correct digit of the root after these initial iterations, an error message is printed. The default value of the initial precision is 5.
The order parameter should give the convergence order of the scheme. Normally, Newton iteration converges quadratically (so the default value is order=2) but some schemes converge faster and you can speed up this function by specifying the correct order. (Caution: if you give order=3 but the sequence is actually quadratic, the result will be silently incorrect. It is safe to use order=2.)
In> Precision(20) Out> True; In> NewtonNum({{x}, x+Sin(x)}, 3, 5, 3) Out> 3.14159265358979323846; |
SumTaylorNum(x, NthTerm, order) SumTaylorNum(x, NthTerm, TermFactor, order) SumTaylorNum(x, ZerothTerm, TermFactor, order) |
ZerothTerm -- value of the 0-th coefficient of the series
x -- number, value of the expansion variable
TermFactor -- a function specifying the ratio of n-th term to the previous one
order -- power of x in the last term
The coefficients a[k] of the Taylor series are given as functions of one integer variable (k). It is convenient to pass them to SumTaylorNum as closures. For example, if a function a(k) is defined, then
SumTaylorNum(x, {{k}, a(k)}, n) |
Often a simple relation between successive coefficients a[k-1], a[k] of the series is available; usually they are related by a rational factor. In this case, the second form of SumTaylorNum should be used because it will compute the series faster. The function TermFactor applied to an integer k>=1 must return the ratio a[k]/a[k-1]. (If possible, the function TermFactor should return a rational number and not a floating-point number.) The function NthTerm may also be given, but the current implementation only calls NthTerm(0) and obtains all other coefficients by using TermFactor. Instead of the function NthTerm, a number giving the 0-th term can be given.
The algorithm is described elsewhere in the documentation. The number of terms order+1 must be specified and a sufficiently high precision must be preset in advance to achieve the desired accuracy. (The function SumTaylorNum does not change the current precision.)
In> Precision(21) Out> True; In> SumTaylorNum(1, {{k},1/k!}, 21) Out> 2.718281828459045235351; In> SumTaylorNum(1, 1, {{k},1/k}, 21) Out> 2.71828182845904523535; In> SumTaylorNum(1, {{k},1/k!}, {{k},1/k}, 21) Out> 2.71828182845904523535; In> RoundTo(N(Ln(%)),20) Out> 1; |
IntPowerNum(x, n, mult, unity) |
n -- a non-negative integer (power to raise x to)
mult -- a function that performs one multiplication
unity -- value of the unity with respect to that multiplication
Mathematically, this function is a generalization of MathPower to rings other than that of real numbers.
In the current implementation, the unity argument is only used when the given power n is zero.
In> IntPowerNum(3, 3, MathMultiply,1) Out> 27; |
In> IntPowerNum(3+4*I, 3, *,1) Out> Complex(-117,44); In> IntPowerNum(HilbertMatrix(2), 4, *, Identity(2)) Out> {{289/144,29/27},{29/27,745/1296}}; |
In> IntPowerNum(3,100,{{x,y},Mod(x*y,7)},1) Out> 4; |
BinSplitNum(n1, n2, a, b, c, d) BinSplitData(n1,n2, a, b, c, d) BinSplitFinal({P,Q,B,T}) |
a, b, c, d -- functions of one argument, coefficients of the series
P, Q, B, T -- numbers, intermediate data as returned by BinSplitData
The last four arguments of BinSplitNum are functions of one argument that give the coefficients a(k), b(k), p(k), q(k). In most cases these will be short integers that are simple to determine. The binary splitting method will work also for non-integer coefficients, but the calculation will take much longer in that case.
Note: the binary splitting method outperforms the straightforward summation only if the multiplication of integers is faster than quadratic in the number of digits. See the algorithm documentation for more information.
The two other functions are low-level functions that allow a finer control over the calculation. The use of the low-level routines allows checkpointing or parallelization of a binary splitting calculation.
The binary splitting method recursively reduces the calculation of S(n[1],n[2]) to the same calculation for the two halves of the interval [n[1], n[2]]. The intermediate results of a binary splitting calculation are returned by BinSplitData and consist of four integers P, Q, B, T. These four integers are converted into the final answer S by the routine BinSplitFinal using the relation
In> Precision(21) Out> True; In> BinSplitNum(1,21, {{k},1}, {{k},1},{{k},1},{{k},k}) Out> 1.718281828459045235359; In> N(Exp(1)-1) Out> 1.71828182845904523536; In> BinSplitData(1,21, {{k},1}, {{k},1},{{k},1},{{k},k}) Out> {1,51090942171709440000,1, 87788637532500240022}; In> BinSplitFinal(%) Out> 1.718281828459045235359; |
MathGetExactBits(x) MathSetExactBits(x,bits) |
bits -- integer, number of bits
MathGetExactBits(x) returns an integer number n such that x represents a real number in the interval [ x*(1-2^(-n)), x*(1+2^(-n))] if x!=0 and in the interval [-2^(-n), 2^(-n)] if x=0. The integer n is always nonnegative unless x is zero (a "floating zero"). A floating zero can have a negative value of the number n of exact bits.
These functions are only meaningful for floating-point numbers. (All integers are always exact.) For integer x, the function MathGetExactBits returns the bit count of x and the function MathSetExactBits returns the unmodified integer x.
In> MathGetExactBits(1000.123) Out> 33; In> x:=MathSetExactBits(10., 20) Out> 10.; In> MathGetExactBits(x) Out> 20; |
In> x:=MathSetExactBits(0., -2) Out> 0.; In> x=0 Out> True; |
Check(predicate,"error text") TrapError(expression,errorHandler) GetCoreError() |
"error text" -- string to print on error
expression -- expression to evaluate (causing potential error)
errorHandler -- expression to be called to handle error
A "soft" error reporting facility that does not stop the execution is provided by the function Assert.
In> [Check(1=0,"bad value"); Echo(OK);] In function "Check" : CommandLine(1) : "bad value" |
Note that OK is not printed.
TrapError evaluates its argument expression, returning the result of evaluating expression. If an error occurs, errorHandler is evaluated, returning its return value in stead.
GetCoreError returns a string describing the core error. TrapError and GetCoreError can be used in combination to write a custom error handler.
Assert("str", expr) pred Assert("str") pred Assert() pred |
"str" -- string to classify the error
expr -- expression, error object
Unlike the "hard" error function Check, the function Assert does not stop the execution of the program.
The error object consists of the string "str" and an arbitrary expression expr. The string should be used to classify the kind of error that has occurred, for example "domain" or "format". The error object can be any expression that might be useful for handling the error later; for example, a list of erroneous values and explanations. The association list of error objects is currently the global variable ErrorTableau.
If the parameter expr is missing, Assert substitutes True. If both optional parameters "str" and expr are missing, Assert creates an error of class "generic".
Errors can be handled by a custom error handler in the portion of the code that is able to handle a certain class of errors. The functions IsError, GetError and ClearError can be used.
Normally, all errors posted to the error tableau during evaluation of an expression should be eventually printed to the screen. This is the behavior of prettyprinters DefaultPrint, Print, PrettyForm and TeXForm (but not of the inline prettyprinter, which is enabled by default); they call DumpErrors after evaluating the expression.
In> Assert("bad value", "must be zero") 1=0 Out> False; In> Assert("bad value", "must be one") 1=1 Out> True; In> IsError() Out> True; In> IsError("bad value") Out> True; In> IsError("bad file") Out> False; In> GetError("bad value"); Out> "must be zero"; In> DumpErrors() Error: bad value: must be zero Out> True; |
In> IsError() Out> False; In> DumpErrors() Out> True; |
DumpErrors() ClearErrors() |
ClearErrors is a trivial error handler that does nothing except it clears the tableau.
IsError() IsError("str") |
GetError("str") ClearError("str") |
GetError returns the error object if a custom error of class "str" has been reported using Assert, or False if no errors of this class have been reported.
ClearError("str") deletes the same error object that is returned by GetError("str"). It deletes at most one error object. It returns True if an object was found and deleted, and False otherwise.
In> x:=1 Out> 1; In> Assert("bad value", {x,"must be zero"}) x=0 Out> False; In> GetError("bad value") Out> {1, "must be zero"}; In> ClearError("bad value"); Out> True; In> IsError() Out> False; |
CurrentFile() CurrentLine() |
These functions are most useful in batch file calculations, where there is a need to determine at which line an error occurred. One can define a function
tst() := Echo({CurrentFile(),CurrentLine()}); |
It is important for a developer to know which functions are built-in and cannot be redefined or Retract-ed. Also, core functions may be somewhat faster to execute than functions defined in the script library. All core functions are listed in the file corefunctions.h in the src/ subdirectory of the Yacas source tree. The declarations typically look like this:
SetCommand(LispSubtract, "MathSubtract"); |
MathNot(expression) |
MathAnd(...) |
MathOr(...) |
MathOr is the basic logical "or" function. Similarly to And, it is lazy-evaluated. And(...) and Or(...) do also exist, defined in the script library. You can redefine them as infix operators yourself, so you have the choice of precedence. In the standard scripts they are in fact declared as infix operators, so you can write expr1 And expr.
BitAnd(n,m) BitOr(n,m) BitXor(n,m) |
Equals(a,b) |
GreaterThan(a,b) LessThan(a,b) |
In> LessThan(1,1) Out> False; In> LessThan("a","b") Out> True; |
MathGcd(n,m) (Greatest Common Divisor) MathAdd(x,y) (add two numbers) MathSubtract(x,y) (subtract two numbers) MathMultiply(x,y) (multiply two numbers) MathDivide(x,y) (divide two numbers) MathSqrt(x) (square root, must be x>=0) MathFloor(x) (largest integer not larger than x) MathCeil(x) (smallest integer not smaller than x) MathAbs(x) (absolute value of x, or |x| ) MathExp(x) (exponential, base 2.718...) MathLog(x) (natural logarithm, for x>0) MathPower(x,y) (power, x ^ y) MathSin(x) (sine) MathCos(x) (cosine) MathTan(x) (tangent) MathSinh(x) (hyperbolic sine) MathCosh(x) (hyperbolic cosine) MathTanh(x) (hyperbolic tangent) MathArcSin(x) (inverse sine) MathArcCos(x) (inverse cosine) MathArcTan(x) (inverse tangent) MathArcSinh(x) (inverse hyperbolic sine) MathArcCosh(x) (inverse hyperbolic cosine) MathArcTanh(x) (inverse hyperbolic tangent) MathDiv(x,y) (integer division, result is an integer) MathMod(x,y) (remainder of division, or x mod y) |
Note that all functions, such as the MathPower, MathSqrt, MathAdd etc., accept integers as well as floating-point numbers. The resulting values may be integers or floats. If the mathematical result is an exact integer, then the integer is returned. For example, MathSqrt(25) returns the integer 5, and MathPower(2,3) returns the integer 8. In such cases, the integer result is returned even if the calculation requires more digits than set by Precision. However, when the result is mathematically not an integer, the functions return a floating-point result which is correct only to the current precision.
In> Precision(10) Out> True In> Sqrt(10) Out> Sqrt(10) In> MathSqrt(10) Out> 3.16227766 In> MathSqrt(490000*2^150) Out> 26445252304070013196697600 In> MathSqrt(490000*2^150+1) Out> 0.264452523e26 In> MathPower(2,3) Out> 8 In> MathPower(2,-3) Out> 0.125 |
FastExp(x), FastLog(x) (natural logarithm), FastPower(x,y), FastSin(x), FastCos(x), FastTan(x), FastArcSin(x), FastArcCos(x), FastArcTan(x)
ShiftLeft(expr,bits) ShiftRight(expr,bits) |
IsPromptShown() |
MathLibrary() |
Possible names supported at the moment are "Internal" and "Gmp", indicating the internal math library libyacasnumbers and the GNU Multiple Precision library libgmp.
In> MathLibrary() Out> "Internal"; |
GetTime(expr) |
The result is the "user time" as reported by the OS, not the real ("wall clock") time. Therefore, any CPU-intensive processes running alongside Yacas will not significantly affect the result of GetTime.
In> GetTime(Simplify((a*b)/(b*a))) Out> 0.09; |
The plugin feature allows Yacas to interface with other libraries that support additional functionality. For example, there could be a plugin enabling the user to script a user interface from within Yacas, or a specific powerful library to do numeric calculations.
The plugin feature is currently in an experimental stage, and it will not work on each platform. To be precise, the libltdl library is used to load the plugins. This will only work on platforms which are supported by libltdl, which includes Linux, Mac OS X, Solaris, and HP-UX.
The remainder of the section is only of interest to users who want to write plugins themselves. It is assumed that the reader is comfortable programming in C++.
In addition to the plugin structure in the Yacas engine, there is a module cstubgen (currently still under development) that allows a rapid creation of a plugin that interfaces to an external library. Essentially all that is required is to write a file that looks like the header file of the original library, but written in Yacas syntax. The module cstubgen is then able to write out a C++ file that can be compiled and linked with the original library, and then loaded from within Yacas. To include a function in the plugin typically takes one line of Yacas code. There are a few examples in the plugins/ directory (the files ending with api.stub). The build system converts these automatically to the required C++ files.
In addition to the C++ stub file, cstubgen also automatically generates some documentation on the functions included in the stub. This documentation is put in a file with extension '.man.txt'.
An example describing the use of cstubgen can be found in the essay "Creating plugins for Yacas" . See Essays on Yacas, Chapter 5 for a description of the integration of plugins in the build system.
DllLoad(file) |
If the argument file does not specify a directory, all directories in the path for Yacas plugins are searched. This path is built up by calls to DllDirectory. In addition, it contains the default plugin directory which is specified by the command line option --dlldir (see The Yacas User's Function Reference, Chapter 1 ). If this option is not present, the default plugin directory is as specified at compile time (the default value is /usr/local/lib/yacas).
If the argument file does not specify the extension, then first the extension .la is appended. This is the standard extension for Libtool libraries. If no plugin with this name can be found, a platform-specific extension is tried (as an example, this is .so on platforms with ELF libraries).
In> DllLoad("example"); Out> True In> AddTwoIntegers(2,3); Out> 5 |
Note that it suffices to specify the string example. Yacas knows that the plugin resides in the file /usr/local/lib/yacas/example.la (if plugins are installed in the default locations).
DllUnload(file) |
DllUnload always returns True, even if no plugin with the name file is found.
In> DllLoad("example"); Out> True In> AddTwoIntegers(2,3); Out> 5 |
Then, we unload the plugin, and we check that the function AddTwoIntegers is indeed no longer defined.
In> DllUnload("example"); Out> True In> AddTwoIntegers(2,3); Out> AddTwoIntegers(2,3) |
DllEnumerate() |
In> DllEnumerate(); Out> {} |
This changes after we load the example plugin.
In> DllLoad("example"); Out> True In> DllEnumerate(); Out> {"example"} |
StubApiCStart(name) |
StubApiCPrettyName(name) |
This name is used for producing documentation. It will appear in the title of the documentation section describing the plugin.
StubApiCPrettyName("multithreaded GUI") |
StubApiCPluginPurpose(text) |
StubApiCShortIntegerConstant(const,value) |
value -- integer value the global should be bound to
#define FOO 10 |
StubApiCShortIntegerConstant("FOO","FOO") |
StubApiCInclude(file) |
StubApiCInclude("\<GL/gl.h\>") |
StubApiCInclude("\"GL/gl.h\"") |
StubApiCFunction(returntype,fname,args) StubApiCFunction(returntype,fname, fname2,args) |
fname -- function of built-in function
fname2 -- (optional) function name to be used from within Yacas
args -- list of arguments to the function
Return type, function name, and list of arguments should be literal strings (surrounded by quotes).
If fname2 is not supplied, it will be assumed to be the same as fname.
The return types currently supported are "int", "double" and "void".
The argument values that are currently supported are "int", "double", and "input_string".
Argument types can be specified simply as a string referring to their type, like "int", or they can be lists with an additional element stating the name of the variable: {"int","n"}. The variable will then show up in the automatically generated documentation as having the name "n".
StubApiCFunction("void","glVertex3d", {"double","double","double"}); |
StubApiCRemark(string) |
StubApiCSetEnv(func) |
There needs to ba a function in the plugin somewhere of the form
static LispEnvironment* env = NULL; void GlutSetEnv(LispEnvironment& aEnv) { env = &aEnv; } |
StubApiCSetEnv("GlutSetEnv"); |
StubApiCFile(pluginname,basename) |
basename -- name for the generation of the stub file
pluginname should be the name as passed to DllLoad. If the plugin name is loaded with DllLoad("example"), then pluginname should be "example".
StubApiCStruct(name) StubApiCStruct(name,freefunction) |
freefunction -- function that can be called to clean up the object
By default the struct will be deleted from memory with a normal call to free(...). This can be overridden with a function given as second argument, freefunction. This is needed in the case where there are additional operations that need to be performed in order to delete the object from memory.
typedef struct SomeStruct { int a; int b; } SomeStruct; |
StubApiCStruct("SomeStruct*") |
IsGeneric(object) |
GenericTypeName(object) |
EG
In> GenericTypeName(ArrayCreate(10,1)) Out> "Array"; |
ArrayCreate(size,init) |
ArraySize(array) |
ArrayGet(array,index) |
Arrays can also be accessed through the [] operators. So array[index] would return the same as ArrayGet(array, index).
ArraySet(array,index,element) |
Arrays can also be accessed through the [] operators. So array[index] := element would do the same as ArraySet(array, index,element).
ArrayCreateFromList(list) |
ListFromArray(array) |
Yacas comes with a test suite which can be found in the directory tests/. Typing
make test |
The verification commands described in this chapter only display the expressions that do not evaluate correctly. Errors do not terminate the execution of the Yacas script that uses these testing commands, since they are meant to be used in test scripts.
Verify(question,answer) TestYacas(question,answer) LogicVerify(question,answer) |
answer -- expected result after evaluation
For some calculations, the demand that two expressions are identical syntactically is too stringent. The Yacas system might change at various places in the future, but 1+x would still be equivalent, from a mathematical point of view, to x+1.
The general problem of deciding that two expressions a and b are equivalent, which is the same as saying that a-b=0 , is generally hard to decide on. The following commands solve this problem by having domain-specific comparisons.
The comparison commands do the following comparison types:
In> Verify(1+2,3) Out> True; In> Verify(x*(1+x),x^2+x) ****************** x*(x+1) evaluates to x*(x+1) which differs from x^2+x ****************** Out> False; In> TestYacas(x*(1+x),x^2+x) Out> True; In> Verify(a And c Or b And Not c,a Or b) ****************** a And c Or b And Not c evaluates to a And c Or b And Not c which differs from a Or b ****************** Out> False; In> LogicVerify(a And c Or b And Not c,a Or b) Out> True; In> LogicVerify(a And c Or b And Not c,b Or a) Out> True; |
KnownFailure(test) |
This might be used by developers when they have no time to fix the defect, but do not wish to alarm users who download Yacas and type make test.
In> KnownFailure(Verify(1,2)) Known failure: ****************** 1 evaluates to 1 which differs from 2 ****************** Out> False; In> KnownFailure(Verify(1,1)) Known failure: Failure resolved! Out> True; |
RoundTo(number,precision) |
precision -- precision to use for round-off
In> N(RoundTo(Exp(1),30),30) Out> 2.71828182110230114951959786552; In> N(RoundTo(Exp(1),20),20) Out> 2.71828182796964237096; |
VerifyArithmetic(x,n,m) RandVerifyArithmetic(n) VerifyDiv(u,v) |
VerifyArithmetic verifies for an arbitrary set of numbers x, n and m that
The left and right side represent two ways to arrive at the same result, and so an arithmetic module actually doing the calculation does the calculation in two different ways. The results should be exactly equal.
RandVerifyArithmetic(n) calls VerifyArithmetic with random values, n times.
VerifyDiv(u,v) checks that
In> VerifyArithmetic(100,50,60) Out> True; In> RandVerifyArithmetic(4) Out> True; In> VerifyDiv(x^2+2*x+3,x+1) Out> True; In> VerifyDiv(3,2) Out> True; |
Yacas allows to define functions with the same name but different arities, and different rules corresponding to these arities will be used. Also, it is possible to define a function with optional arguments, for example, Plot2D is one such function. Such functions can have any arity larger or equal to a certain minimum arity (the number of non-optional arguments).
Arrays are faster than lists but the array size cannot be changed.
Atoms can be of type string, number, or symbol. For example, y1 is a symbolic atom, 954 is a number atom, and "" is an (empty) string atom. Symbolic atoms are normally used in Yacas to denote mathematical unknowns and function names. Number and string atoms are used to denote values.
A symbolic atom can be bound to a value (in which case it becomes a variable), or to a rule or several rules (in which case it becomes a function). An atom can also have a property object.
Some constants take a long time to compute and therefore they are cached at the highest precision computed so far. These are the "cached constants".
In> Solve(Sin(x)==1, x) Out> {x==Pi/2}; |
The symbolic equation operator == is also useful to represent solutions of equations or to specify substitutions, give options, and so on.
Functions can be evaluated, that is, the rules bound to them may be executed. For example, Cos(Pi+0) is an expression that contains two functions and four atoms. The atom Pi is a symbolic atom which is normally not bound to anything. The atom 0 is a numeric atom.
The atoms Cos and + are symbolic atoms which are bound to appropriate simplification rules. So these two atoms are functions. Note that these functions have different syntax. Cos is a normal function which takes its arguments in parentheses. The atom + is a function with special syntax because "+" is placed between its arguments and no parentheses are used.
The rules to which + is bound are such that the expression Pi+0 is evaluated to the symbolic atom Pi. The rules for Cos are such that the expression Cos(Pi) is evaluated to the numeric atom -1. The example Yacas session is:
In> Cos(Pi+0) Out> -1; |
Some functions are built-in and implemented in C++, while others are library functions.
The built-in functions are usually less flexible than the library functions because they cannot be left unevaluated. Given incorrect arguments, a built-in function will generate an error. However, a user-defined function may simply return unevaluated in such cases.
Lists are ubiquitous in Yacas. Most data structures in the standard library is based on lists.
Lists are also used internally to represent Yacas expressions. For example, the expression Cos(x+1) is represented internally as a nested list:
In> FullForm( Cos(x+1) ) (Cos (+ x 1 )) Out> Cos(x+1); |
Some basic linear algebra operations on matrices are supported.
Apart from the syntax, operators are exactly the same as any other functions, they can have rules bound to them in the same way.
For example, the operator "+" binds less tightly (i.e. has a higher precedence value) than the operator "*" and so the expression a+b*c is parsed as a+(b*c), as one would expect.
Infix operators can have different left-side and right-side precedence. For example, the infix operator "-" has left precedence 70 and right precedence 40 -- this allows us to parse expressions such as a-b+c correctly, as a-b+c, and not as a-(b+c).
In> a:= SetExtraInfo(1+x,y); Out> 1+x; |
In> func1(x+0) Out> func1(x); |
Only expressions containing functions can be evaluated by rules. (Atoms are evaluated only if they are bound to a value.)
Several rules can be defined for a given function. Rules can be erased or added at run time.
In> D(x) Sin(x)+1 Out> Cos(x); |
Functions with special syntax can have different precedence.
In> a := 1 Out> 1; |
GNU GENERAL PUBLIC LICENSE Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
When we speak of free software, we are referring to freedom, 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 or use pieces of it in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification follow.
GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's 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 give any other recipients of the Program a copy of this License along with the Program.
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 Program or any portion of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, 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 Program, 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 Program.
In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
a) 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; or,
b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for making modifications to it. For an executable work, 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 executable. However, as a special exception, the source code 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.
If distribution of executable or 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 counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program 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.
5. 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 Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program 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 to this License.
7. 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 Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program 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 Program.
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.
8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program 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.
9. The Free Software Foundation may publish revised and/or new versions of the 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 Program 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 Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, 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.
12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
To do so, attach the following notices to the program. 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 program's name and a brief idea of what it does.> Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice
This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.
59 Temple Place, Suite 330 Boston, MA, 02111-1307 USA |
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
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.
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.
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.
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. (For example, 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.
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.
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 ``Transparent'' copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and 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 has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is not ``Transparent'' is called ``Opaque''.
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 designed for human modification. Opaque formats include PostScript, PDF, 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 produced by some word processors for output purposes only.
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.
You may also lend copies, under the same conditions stated above, and you may publicly display copies.
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.
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 publicly-accessible computer-network location containing a complete Transparent copy of the Document, free of added material, which the general network-using public has access to download anonymously at no charge using public-standard network protocols. 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.
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.
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.
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.
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.
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.
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.
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.''
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.
If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one quarter of the entire aggregate, the Document's Cover Texts may be placed on covers that surround only the Document within the aggregate. Otherwise they must appear on covers around the whole aggregate.
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.
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.1 or any later version published by the Free Software Foundation; with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. A copy of the license is included in the section entitled ``GNU Free Documentation License''. |
If you have no Invariant Sections, write ``with no Invariant Sections'' instead of saying which ones are invariant. If you have no Front-Cover Texts, write ``no Front-Cover Texts'' instead of ``Front-Cover Texts being LIST''; likewise for Back-Cover Texts.
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.