====================================================================
Factored examples
====================================================================

Factored creates a domain whose objects are kept in factored form as
long as possible.  Thus certain operations like * (multiplication) and
gcd are relatively easy to do.  Others, such as addition, require
somewhat more work, and the result may not be completely factored
unless the argument domain R provides a factor operation.  Each object
consists of a unit and a list of factors, where each factor consists
of a member of R (the base), an exponent, and a flag indicating what
is known about the base.  A flag may be one of "nil", "sqfr", "irred"
or "prime", which mean that nothing is known about the base, it is
square-free, it is irreducible, or it is prime, respectively.  The
current restriction to factored objects of integral domains allows
simplification to be performed without worrying about multiplication
order.

====================================================================
Decomposing Factored Objects
====================================================================

In this section we will work with a factored integer.

  g := factor(4312)
     3 2
    2 7 11
                         Type: Factored Integer

Let's begin by decomposing g into pieces.  The only possible
units for integers are 1 and -1.

  unit(g)
    1
                         Type: PositiveInteger

There are three factors.

  numberOfFactors(g)
    3
                         Type: PositiveInteger

We can make a list of the bases, ...

  [nthFactor(g,i) for i in 1..numberOfFactors(g)]
    [2,7,11]
                         Type: List Integer

and the exponents, ...

  [nthExponent(g,i) for i in 1..numberOfFactors(g)] 
    [3,2,1]
                         Type: List Integer

and the flags.  You can see that all the bases (factors) are prime.

  [nthFlag(g,i) for i in 1..numberOfFactors(g)] 
    ["prime","prime","prime"]
                         Type: List Union("nil","sqfr","irred","prime")

A useful operation for pulling apart a factored object into a list
of records of the components is factorList.

  factorList(g) 
    [[flg= "prime",fctr= 2,xpnt= 3], [flg= "prime",fctr= 7,xpnt= 2],
     [flg= "prime",fctr= 11,xpnt= 1]]
           Type: List Record(flg: Union("nil","sqfr","irred","prime"),
                             fctr: Integer,xpnt: Integer)

If you don't care about the flags, use factors.

  factors(g) 
    [[factor= 2,exponent= 3],[factor= 7,exponent= 2],[factor= 11,exponent= 1]]
                         Type: List Record(factor: Integer,exponent: Integer)

Neither of these operations returns the unit.

  first(%).factor 
    2
                         Type: PositiveInteger

====================================================================
Expanding Factored Objects
====================================================================

Recall that we are working with this factored integer.

  g := factor(4312) 
     3 2
    2 7 11
                         Type: Factored Integer

To multiply out the factors with their multiplicities, use expand.

  expand(g)
    4312
                         Type: PositiveInteger

If you would like, say, the distinct factors multiplied together but
with multiplicity one, you could do it this way.

  reduce(*,[t.factor for t in factors(g)]) 
    154
                         Type: PositiveInteger

====================================================================
Arithmetic with Factored Objects
====================================================================

We're still working with this factored integer.

  g := factor(4312) 
     3 2
    2 7 11
                         Type: Factored Integer

We'll also define this factored integer.

  f := factor(246960) 
     4 2   3
    2 3 5 7
                         Type: Factored Integer

Operations involving multiplication and division are particularly
easy with factored objects.

  f * g 
     7 2   5
    2 3 5 7 11
                         Type: Factored Integer

  f**500 
     2000 1000 500 1500
    2    3    5   7
                         Type: Factored Integer

  gcd(f,g) 
     3 2
    2 7
                         Type: Factored Integer

  lcm(f,g) 
     4 2   3
    2 3 5 7 11
                         Type: Factored Integer

If we use addition and subtraction things can slow down because
we may need to compute greatest common divisors.

  f + g 
     3 2
    2 7 641
                         Type: Factored Integer

  f - g 
     3 2
    2 7 619
                         Type: Factored Integer

Test for equality with 0 and 1 by using zero? and one?, respectively.

  zero?(factor(0))
    true
                         Type: Boolean

  zero?(g) 
    false
                         Type: Boolean

  one?(factor(1))
    true
                         Type: Boolean

  one?(f) 
    false
                         Type: Boolean

Another way to get the zero and one factored objects is to use
package calling.

  0$Factored(Integer)
    0
                         Type: Factored Integer

  1$Factored(Integer)
    1
                         Type: Factored Integer

====================================================================
Creating New Factored Objects
====================================================================

The map operation is used to iterate across the unit and bases of a
factored object.

The following four operations take a base and an exponent and create a
factored object.  They differ in handling the flag component.

  nilFactor(24,2) 
      2
    24
                         Type: Factored Integer

This factor has no associated information.

  nthFlag(%,1) 
    "nil"
                         Type: Union("nil",...)

This factor is asserted to be square-free.

  sqfrFactor(30,2)
      2
    30
                         Type: Factored Integer

This factor is asserted to be irreducible.

  irreducibleFactor(13,10) 
      10
    13
                         Type: Factored Integer

This factor is asserted to be prime.

  primeFactor(11,5) 
      5
    11
                         Type: Factored Integer

A partial inverse to factorList is makeFR.

  h := factor(-720) 
       4 2
    - 2 3 5
                         Type: Factored Integer

The first argument is the unit and the second is a list of records as
returned by factorList.

  h - makeFR(unit(h),factorList(h))
    0
                         Type: Factored Integer

====================================================================
Factored Objects with Variables
====================================================================

Some of the operations available for polynomials are also available
for factored polynomials.

  p := (4*x*x-12*x+9)*y*y + (4*x*x-12*x+9)*y + 28*x*x - 84*x + 63 
       2            2      2                  2
    (4x  - 12x + 9)y  + (4x  - 12x + 9)y + 28x  - 84x + 63
                         Type: Polynomial Integer

  fp := factor(p) 
            2  2
    (2x - 3) (y  + y + 7)
                         Type: Factored Polynomial Integer

You can differentiate with respect to a variable.

  D(p,x) 
              2
    (8x - 12)y  + (8x - 12)y + 56x - 84
                         Type: Polynomial Integer

  D(fp,x) 
               2
    4(2x - 3)(y  + y + 7)
                         Type: Factored Polynomial Integer

  numberOfFactors(%) 
    3
                         Type: PositiveInteger

See Also:
o )help FactoredFunctions2
o )show Factored

