Factorization package
- To: mathgroup at christensen.cybernetics.net
- Subject: [mg803] Factorization package
- From: Dave Wagner <wagner at bullwinkle.cs.Colorado.EDU>
- Date: Fri, 21 Apr 1995 01:42:24 -0400
Okay group, here's the package that I promised. Note that this is a "Call for Comments." Please don't clutter up the net/mailing list with comments directed to me; e-mail them to me directly (dbwagner at csn.net) and I will summarize all at once. Some background: Alan Powell (powella at delphi.com) asked: >>Could anyone suggest a neat way to reformat the output of >>FactorInteger into a more usable print format? >< details deleted > To which I replied that the best thing to do would be to convert an expression like {{2,2}},{3,4}} (the result of FactorInteger) to something like HoldForm[Times[Power[2,2], Power[3,4]]], which would print as 2 4 2 3 Later I posted another message saying that this was doing things the hard way, and that all that was necessary was to define a new head called IntegerPower like this: Format[IntegerPower[a_,b_]] := HoldForm[Power[a,b]] and then convert the factorization shown above to Times[IntegerPower[2,2], IntegerPower[3,4]]. I noted that it wasn't really necessary to have a special head for expressions like this. WELL, I WAS WRONG, inasmuch as if you want to try to make these beasties behave like a built-in type, it is much easier if you give them a readily-identifiable head. In particular, without such a head there are two possible representations of a factorization: Time[__IntegerPower] and IntegerPower[_,_] (for numbers with only one prime factor). This complicates things enormously. So, I've written a package that defines a new "type" called Factorization, which looks simply like Factorization[{2,2}, {3,4}]. You can add, multiply, and exponentiate factorizations together with other numbers to your hearts' desire. In addition, the built-in function FactorInteger is overridden to return a Factorization directly. I've also defined an inverse function, ExpandInteger. Here are some examples: f1 = FactorInteger[3^2] 2 3 f1 + 4^2 2 5 % + 1325 3 2 2 3 5 % ^ 2 2 6 4 2 3 5 1/% -2 -6 -4 2 3 5 f2 = FactorInteger[238500] 2 2 3 2 3 5 53 Sqrt[f2] 3/2 1/2 2 3 5 53 N[%] 488.365 f4 = FactorInteger[40 + 18I] 2 -1 (1 + I) (1 + 6 I) (3 + 2 I) f4 + 1 -I (1 + 20 I) (2 + I) ExpandInteger[%] 41 + 18 I f4 + .5 40.5 + 18 I Complex numbers are kind of a thorny problem -- when I add, for example, 2^2 + 4+I I don't know whether it would be better to return 2^3 + I or FactorInteger[8+I] = -I (1+2I) (3+2I). Currently I do the latter; I've thought of perhaps doing the former and overriding, say, Together, to go the rest of the way. But I hesitate to pollute the definition of Together like that. Comments? I've made a start on UpValues for all of the numerical functions, but there are so many that I decided to take a rest for a couple of days. Here is an example of one of my better efforts: FactorInteger[7/9] -2 3 7 Cos[% Pi] -2 Cos[Pi 3 7] FactorInteger[7/6] -1 -1 2 3 7 Cos[% Pi] -Sqrt[3] -------- 2 Be advised that some of the built-in functions that I haven't gotten to yet may hit $RecursionLimit as a result of the overridden definitions of Plus and Times. ComplexExpand, Arg, and Abs were like that until I fixed them. Unfortunately, I'm working alphabetically and I'm only up to "Delete"! In the meantime, I was hoping that members of the group would beat on this package and try to find bugs (keeping in mind the disclaimer in the previous paragraph). I particularly would like input on design issues, such as when I should and should not assume the user wants a factorization converted to a number or vice-versa. The package is appended below in notebook format. To use it, you can open it directly and reply "Yes" to "Evaluate Initialization Cells?". Or, save it in a file called "Factorization.m", put the file in a place where Mathematica will find it (see $Path), and evaluate Needs["Factorization`"]. There are some examples of use at the beginning of the notebook. Dave Wagner Principia Consulting (303) 786-8371 princon at csn.net http://www.csn.net/princon ----------------- CLIP HERE and save in "Factorization.m" ------------------- (*^ ::[ Information = "This is a Mathematica Notebook file. It contains ASCII text, and can be transferred by email, ftp, or other text-file transfer utility. It should be read or edited using a copy of Mathematica or MathReader. If you received this as email, use your mail application or copy/paste to save everything from the line containing (*^ down to the line containing ^*) into a plain text file. On some systems you may have to give the file a name ending with ".ma" to allow Mathematica to recognize it as a Notebook. The line below identifies what version of Mathematica created this file, but it can be opened using any other version as well."; FrontEndVersion = "Macintosh Mathematica Notebook Front End Version 2.2"; MacintoshStandardFontEncoding; fontset = title, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeTitle, center, M7, bold, e8, 24, "Times"; fontset = subtitle, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeTitle, center, M7, bold, e6, 18, "Times"; fontset = subsubtitle, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeTitle, center, M7, italic, e6, 14, "Times"; fontset = section, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeSection, grayBox, M22, bold, a20, 18, "Times"; fontset = subsection, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeSection, blackBox, M19, bold, a15, 14, "Times"; fontset = subsubsection, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeSection, whiteBox, M18, bold, a12, 12, "Times"; fontset = text, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, "Times"; fontset = smalltext, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, R14534, G103, B37603, 12, "Times"; fontset = input, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeInput, M42, N23, bold, L-5, 12, "Courier"; fontset = output, output, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeOutput, M42, N23, L-5, 12, "Courier"; fontset = message, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeOutput, M42, N23, R65535, L-5, 12, "Courier"; fontset = print, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeOutput, M42, N23, L-5, 12, "Courier"; fontset = info, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeOutput, M42, N23, B65535, L-5, 12, "Courier"; fontset = postscript, PostScript, formatAsPostScript, output, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeGraphics, M7, l34, w282, h287, 12, "Courier"; fontset = name, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, italic, R65535, B65535, 10, "Geneva"; fontset = header, inactive, noKeepOnOnePage, preserveAspect, M7, 12, "Times"; fontset = leftheader, inactive, L2, 12, "Times"; fontset = footer, inactive, noKeepOnOnePage, preserveAspect, center, M7, 12, "Times"; fontset = leftfooter, inactive, L2, 12, "Times"; fontset = help, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 10, "Times"; fontset = clipboard, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, "Times"; fontset = completions, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, "Times"; fontset = special1, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, bold, 18, "Times"; fontset = special2, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, bold, 14, "Times"; fontset = special3, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, bold, 12, "Times"; fontset = special4, inactive, nohscroll, noKeepOnOnePage, preserveAspect, blackDot, M27, 12, "Times"; fontset = special5, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M27, 12, "Times"; paletteColors = 128; showRuler; automaticGrouping; currentKernel; ] :[font = title; inactive; preserveAspect; startGroup] Factorization` Abstract Data Type Package :[font = section; inactive; preserveAspect; startGroup] Demonstration of use :[font = input; preserveAspect; startGroup] ?FactorInteger :[font = print; inactive; preserveAspect; endGroup] FactorInteger[n] gives a list of the prime factors of the integer n, together with their exponents. The returned list is wrapped in the head Factorization. :[font = input; preserveAspect; startGroup] ?Factorization :[font = print; inactive; preserveAspect; endGroup] Factorization[{n1, p1}, {n2, p2}, ...] represents the number n1^p1 * n2^p2 * ... :[font = input; preserveAspect; startGroup] f1 = FactorInteger[3^2] :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{3, 2}] ;[o] 2 3 :[font = input; preserveAspect; startGroup] f1 + 4^2 :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{5, 2}] ;[o] 2 5 :[font = input; preserveAspect; startGroup] % + 1325 :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{2, 1}, {3, 3}, {5, 2}] ;[o] 3 2 2 3 5 :[font = input; preserveAspect; startGroup] % ^ 2 :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{2, 2}, {3, 6}, {5, 4}] ;[o] 2 6 4 2 3 5 :[font = input; preserveAspect; startGroup] 1/% :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{2, -2}, {3, -6}, {5, -4}] ;[o] -2 -6 -4 2 3 5 :[font = input; preserveAspect; startGroup] Sqrt[%] :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{2, -1}, {3, -3}, {5, -2}] ;[o] -1 -3 -2 2 3 5 :[font = input; preserveAspect; startGroup] ExpandInteger[%] :[font = output; output; inactive; preserveAspect; endGroup] 1/1350 ;[o] 1 ---- 1350 :[font = text; inactive; preserveAspect] Here is an example in which a factorization, through manipulation, no longer represents a rational number. :[font = input; preserveAspect; startGroup] f2 = FactorInteger[238500] :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{2, 2}, {3, 2}, {5, 3}, {53, 1}] ;[o] 2 2 3 2 3 5 53 :[font = input; preserveAspect; startGroup] Sqrt[f2] :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{2, 1}, {3, 1}, {5, 3/2}, {53, 1/2}] ;[o] 3/2 1/2 2 3 5 53 :[font = text; inactive; preserveAspect] Note that a Factorization can be numericalized without first converting it back to a number. :[font = input; preserveAspect; startGroup] N[%] :[font = output; output; inactive; preserveAspect; endGroup] 488.3646178829912 ;[o] 488.365 :[font = input; preserveAspect; startGroup] ExpandInteger[Sqrt[f2]] :[font = output; output; inactive; preserveAspect; endGroup] 30*265^(1/2) ;[o] 30 Sqrt[265] :[font = input; preserveAspect; startGroup] N[%] :[font = output; output; inactive; preserveAspect; endGroup] 488.3646178829912 ;[o] 488.365 :[font = text; inactive; preserveAspect] Factors of -1 are always stand alone in a factorization, and are combined as necessary. :[font = input; preserveAspect; startGroup] f3 = FactorInteger[-3] :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{-1, 1}, {3, 1}] ;[o] -1 3 :[font = input; preserveAspect; startGroup] f3 ^ 2 :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{3, 2}] ;[o] 2 3 :[font = input; preserveAspect; startGroup] Sqrt[f3] :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{-1, 1/2}, {3, 1/2}] ;[o] 1/2 1/2 -1 3 :[font = input; preserveAspect; startGroup] ExpandInteger[%] :[font = output; output; inactive; preserveAspect; endGroup] I*3^(1/2) ;[o] I Sqrt[3] :[font = text; inactive; preserveAspect] Complex numbers are factored over the Gaussian integers. :[font = input; preserveAspect; startGroup] f4 = FactorInteger[40 + 18I] :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{-1, 1}, {1 + I, 2}, {1 + 6*I, 1}, {3 + 2*I, 1}] ;[o] 2 -1 (1 + I) (1 + 6 I) (3 + 2 I) :[font = input; preserveAspect; startGroup] f4 + 1 :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{-I, 1}, {1 + 20*I, 1}, {2 + I, 1}] ;[o] -I (1 + 20 I) (2 + I) :[font = input; preserveAspect; startGroup] ExpandInteger[%] :[font = output; output; inactive; preserveAspect; endGroup] 41 + 18*I ;[o] 41 + 18 I :[font = text; inactive; preserveAspect] Adding an inexact number to any factorization numericalizes it. :[font = input; preserveAspect; startGroup] f4 + .5 :[font = output; output; inactive; preserveAspect; endGroup] 40.5 + 18*I ;[o] 40.5 + 18 I :[font = input; preserveAspect; startGroup] f1 + .5 :[font = output; output; inactive; preserveAspect; endGroup] 9.5 ;[o] 9.5 :[font = text; inactive; preserveAspect] Powers can be made in any combination, except that when a factorization is used as aexponent, the exponent is first expanded. :[font = input; preserveAspect; startGroup] {f1, f3} :[font = output; output; inactive; preserveAspect; endGroup] {Factorization[{3, 2}], Factorization[{-1, 1}, {3, 1}]} ;[o] 2 {3 , -1 3} :[font = input; preserveAspect; startGroup] f1 ^ f3 :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{3, -6}] ;[o] -6 3 :[font = input; preserveAspect; startGroup] f3 ^ f1 :[font = output; output; inactive; preserveAspect; endGroup] Factorization[{-1, 1}, {3, 9}] ;[o] 9 -1 3 :[font = input; preserveAspect; startGroup] f1 ^ 2.5 :[font = output; output; inactive; preserveAspect; endGroup] 243. ;[o] 243. :[font = input; preserveAspect; startGroup] 2.5 ^ f1 :[font = output; output; inactive; preserveAspect; endGroup] 3814.697265625 ;[o] 3814.7 :[font = input; preserveAspect; startGroup] 2 ^ f1 :[font = output; output; inactive; preserveAspect; endGroup; endGroup] Factorization[{2, 9}] ;[o] 9 2 :[font = section; inactive; initialization; preserveAspect; startGroup] Implementation :[font = subsection; inactive; preserveAspect; startGroup] Public part of package :[font = input; initialization; preserveAspect] *) BeginPackage["Factorization`"]; (* :[font = subsubsection; inactive; preserveAspect; startGroup] Usage messages :[font = input; initialization; preserveAspect] *) Factorization::usage = "Factorization[{n1, p1}, {n2, p2}, ...] represents the number n1^p1 * n2^p2 * ..."; (* :[font = input; initialization; preserveAspect] *) If[StringPosition[FactorInteger::usage, "Factorization"] === {}, FactorInteger::usage = FactorInteger::usage <> " " <> " The returned list is wrapped in the head Factorization." ]; (* :[font = input; initialization; preserveAspect] *) ExpandInteger::usage = "ExpandInteger[factzn] converts the Factorization factzn to an integer, if possible."; (* :[font = input; initialization; preserveAspect; endGroup; endGroup] *) ExpandAllInteger::usage = "ExpandAllInteger[expr] maps ExpandInteger onto every part of expr."; (* :[font = subsection; inactive; preserveAspect; startGroup] Private part of package :[font = input; initialization; preserveAspect] *) Begin["`Private`"]; (* :[font = subsubsection; inactive; preserveAspect; startGroup] FormatValues :[font = input; initialization; preserveAspect; startGroup] *) fmtrule1 = { c:Complex[x_ /; x!=0, y_ /; y!=0] -> SequenceForm["(", c, ")"] } (* :[font = output; output; inactive; initialization; preserveAspect; endGroup] {c:Complex[x_ /; x != 0, y_ /; y != 0] -> "("c")"} ;[o] {c:Complex[x_ /; x != 0, y_ /; y != 0] -> (c)} :[font = input; initialization; preserveAspect] *) fmtrule2 = { {a_, 1} -> SequenceForm[a, " "], {a_, b_} -> SequenceForm[a, Superscript[b], " "] }; (* :[font = input; initialization; preserveAspect; endGroup] *) Format[x_Factorization] := (SequenceForm @@ x) /. fmtrule1 /. fmtrule2 // Flatten // Drop[#, -1]& (* :[font = subsubsection; inactive; preserveAspect; startGroup] Simplification of special cases :[font = input; initialization; preserveAspect] *) Factorization[] := 1 (* :[font = input; initialization; preserveAspect] *) Factorization[{a_, 1}] := a (* :[font = input; initialization; preserveAspect] *) Factorization[h___, {x_, 0}, t___] := Factorization[h, t] (* :[font = input; initialization; preserveAspect] *) Factorization[h___, {-1, n_?OddQ /; n>1}, t___] := Factorization[h, {-1, 1}, t] (* :[font = input; initialization; preserveAspect] *) Factorization[h___, {-1, n_?EvenQ}, t___] := Factorization[h, t] (* :[font = input; initialization; preserveAspect] *) SetAttributes[Factorization, Orderless] (* :[font = input; initialization; preserveAspect; endGroup] *) Factorization[h___, {a_, b_}, {a_, c_}, t___] := Factorization[h, {a, b+c}, t] (* :[font = subsubsection; inactive; preserveAspect; startGroup] Expanding factorizations :[font = input; initialization; preserveAspect] *) ExpandInteger[x_Factorization] := Times @@ Apply[Power, x, {1}] (* :[font = input; initialization; preserveAspect] *) ExpandInteger[x_] := x (* :[font = text; inactive; preserveAspect] This rule is used by the addition rules that come later. :[font = input; initialization; preserveAspect] *) ExpandInteger[x__] := Sequence @@ ExpandInteger /@ {x} (* :[font = input; initialization; preserveAspect; endGroup] *) ExpandAllInteger[x_] := MapAll[ExpandInteger, x] (* :[font = subsubsection; inactive; preserveAspect; startGroup] NValues :[font = input; initialization; preserveAspect] *) N[x_Factorization, ___] := ExpandInteger[x] (* :[font = input; initialization; preserveAspect; endGroup] *) wasProtected = Unprotect[NumberQ]; NumberQ[_Factorization] := True Protect @@ wasProtected; (* :[font = subsubsection; inactive; preserveAspect; startGroup] Utility functions :[font = input; initialization; preserveAspect] *) exact[x_] := NumberQ[x] && (Precision[x] == Infinity) (* :[font = input; initialization; preserveAspect; endGroup] *) inexact[x_] := NumberQ[x] && (Precision[x] < Infinity) (* :[font = subsubsection; inactive; initialization; preserveAspect; startGroup] Overriding FactorInteger :[font = input; initialization; preserveAspect] *) wasProtected = Unprotect[FactorInteger]; (* :[font = input; initialization; preserveAspect] *) FactorInteger[x_Factorization] := x (* :[font = input; initialization; preserveAspect] *) intercept = True; FactorInteger[x_?exact, opts___Rule] /; intercept := Block[{intercept = False}, (* no recursion *) Factorization @@ FactorInteger[x, opts] ] (* :[font = input; initialization; preserveAspect; endGroup] *) Protect @@ wasProtected; (* :[font = subsubsection; inactive; preserveAspect; startGroup] Multiplication rules :[font = input; initialization; preserveAspect] *) Factorization /: x_Factorization * y_Factorization := Join[x, y] (* :[font = input; initialization; preserveAspect] *) Factorization /: Times[x_Factorization, y_?inexact] := N[x] y (* :[font = input; initialization; preserveAspect; endGroup] *) Factorization /: Times[x_Factorization, y_?exact /; y!=0] := Factorization @@ Block[{intercept = False}, Join[List @@ x, FactorInteger[y]] ] (* :[font = subsubsection; inactive; preserveAspect; startGroup] Rules for exponentiation :[font = input; initialization; preserveAspect] *) Factorization /: Power[x_?exact, y_Factorization] := FactorInteger[x^ExpandInteger[y]] (* :[font = input; initialization; preserveAspect] *) Factorization /: Power[x_, y_Factorization] := x^ExpandInteger[y] (* :[font = input; initialization; preserveAspect] *) Factorization /: Power[x_Factorization, y_?inexact] := N[x]^y (* :[font = input; initialization; preserveAspect; endGroup] *) Factorization /: Power[x_Factorization, y_?exact] := x /. {n_, p_} -> {n, p y} (* :[font = subsubsection; inactive; preserveAspect; startGroup] Addition rules :[font = input; initialization; preserveAspect] *) Factorization /: Plus[x_?inexact, y__Factorization] := Plus[x, ExpandInteger[y]] (* :[font = input; initialization; preserveAspect; endGroup; endGroup] *) Factorization /: Plus[x_?exact, y__Factorization] := FactorInteger[Plus[ExpandInteger[x, y]]] (* :[font = subsection; inactive; preserveAspect; startGroup] The following two sections are "under construction" :[font = subsubsection; inactive; preserveAspect; startGroup] Miscellaneous numerical functions :[font = text; inactive; preserveAspect] UpValues for Factorization :[font = input; initialization; preserveAspect] *) Abs[x_Factorization] ^:= Abs[ExpandInteger[x]] (* :[font = input; initialization; preserveAspect] *) Arg[x_Factorization] ^:= Arg[ExpandInteger[x]] (* :[font = input; initialization; preserveAspect] *) BernoulliB[x_Factorization] ^:= BernoulliB[ExpandInteger[x]] BernoulliB[n_Factorization, x_] ^:= BernoulliB[ExpandInteger[n], x] (* :[font = input; initialization; preserveAspect] *) BesselI[n_Factorization, z_?inexact] ^:= BesselI[ExpandInteger[n], z] BesselJ[n_Factorization, z_?inexact] ^:= BesselJ[ExpandInteger[n], z] BesselK[n_Factorization, z_?inexact] ^:= BesselK[ExpandInteger[n], z] BesselY[n_Factorization, z_?inexact] ^:= BesselY[ExpandInteger[n], z] (* :[font = input; initialization; preserveAspect] *) Beta[a_Factorization, b_] ^:= Beta[ExpandInteger[a], b] Beta[a_, b_Factorization] ^:= Beta[a, ExpandInteger[b]] (* :[font = input; initialization; preserveAspect] *) BetaRegularized[z_?inexact, a_Factorization, b_?NumberQ] ^:= BetaRegularized[z, ExpandInteger[a], b] BetaRegularized[z_?inexact, a_?NumberQ, b_Factorization] ^:= BetaRegularized[z, a, ExpandInteger[b]] (* :[font = input; initialization; preserveAspect] *) Binomial[n_Factorization, m_?NumberQ] ^:= Binomial[ExpandInteger[n], m] Binomial[n_, m_Factorization] ^:= Binomial[n, ExpandInteger[m]] (* :[font = input; initialization; preserveAspect] *) Ceiling[x_Factorization] ^:= Ceiling[ExpandInteger[x]] (* :[font = input; initialization; preserveAspect] *) ChebyshevT[n_Factorization, x_] ^:= ChebyshevT[ExpandInteger[n], x] ChebyshevU[n_Factorization, x_] ^:= ChebyshevU[ExpandInteger[n], x] (* :[font = input; initialization; preserveAspect] *) Conjugate[z_Factorization] ^:= FactorInteger[Conjugate[ExpandInteger[z]]] (* :[font = input; initialization; preserveAspect] *) Cyclotomic[n_Factorization, x_] ^:= Cyclotomic[ExpandInteger[n], x] (* :[font = input; initialization; preserveAspect] *) Factorization /: Derivative[h___, n_Factorization, t___] := Derivative[h, ExpandInteger[n], t] (* :[font = input; initialization; preserveAspect] *) Divisors[x_Factorization] ^:= Divisors[ExpandInteger[x]] (* :[font = input; initialization; preserveAspect; endGroup] *) Factorization /: DivisorSigma[k_Factorization, x_Integer] := FactorInteger[DivisorSigma[ExpandInteger[k], x]] Factorization /: DivisorSigma[k_Integer, x_Factorization] := FactorInteger[DivisorSigma[k, ExpandInteger[x]]] Factorization /: DivisorSigma[k_Factorization, x_Factorization] := FactorInteger[DivisorSigma[ExpandInteger[k, x]]] (* :[font = subsubsection; inactive; preserveAspect; startGroup] Other functions :[font = input; initialization; preserveAspect] *) wasProtected = Unprotect[ComplexExpand, D, Delete, Cos, Sin, Sec, Csc, Tan, Cot]; (* :[font = input; initialization; preserveAspect] *) D[f_, h___, {x_, n_Factorization}, t___] := D[f, h, {x, ExpandInteger[n]}, t] (* :[font = input; initialization; preserveAspect] *) Delete[expr_, n_ /; !FreeQ[n, Factorization]] := Delete[expr, ExpandAllInteger[n]] (* :[font = input; initialization; preserveAspect] *) ComplexExpand[x_ /; !FreeQ[x, Factorization]] := ComplexExpand[ExpandAllInteger[x]] (* :[font = input; initialization; preserveAspect] *) Cos[x_Factorization Pi] := Cos[ExpandInteger[x] Pi] /; With[{y = ExpandInteger[x]}, IntegerQ[2y] || IntegerQ[3y] || IntegerQ[4y] || IntegerQ[6y] ] (* :[font = input; initialization; preserveAspect] *) Sin[x_Factorization Pi] := Sin[ExpandInteger[x] Pi] /; With[{y = ExpandInteger[x]}, IntegerQ[2y] || IntegerQ[3y] || IntegerQ[4y] || IntegerQ[6y] ] (* :[font = input; initialization; preserveAspect] *) Sec[x_Factorization Pi] := Sec[ExpandInteger[x] Pi] /; With[{y = ExpandInteger[x]}, IntegerQ[2y] || IntegerQ[3y] || IntegerQ[4y] || IntegerQ[6y] ] (* :[font = input; initialization; preserveAspect] *) Csc[x_Factorization Pi] := Csc[ExpandInteger[x] Pi] /; With[{y = ExpandInteger[x]}, IntegerQ[2y] || IntegerQ[3y] || IntegerQ[4y] || IntegerQ[6y] ] (* :[font = input; initialization; preserveAspect] *) Tan[x_Factorization Pi] := Tan[ExpandInteger[x] Pi] /; With[{y = ExpandInteger[x]}, IntegerQ[2y] || IntegerQ[3y] || IntegerQ[4y] || IntegerQ[6y] ] (* :[font = input; initialization; preserveAspect] *) Cot[x_Factorization Pi] := Cot[ExpandInteger[x] Pi] /; With[{y = ExpandInteger[x]}, IntegerQ[2y] || IntegerQ[3y] || IntegerQ[4y] || IntegerQ[6y] ] (* :[font = input; initialization; preserveAspect; endGroup; endGroup] *) Protect @@ wasProtected; (* :[font = subsection; inactive; preserveAspect; startGroup] Cleanup :[font = input; initialization; preserveAspect] *) End[]; (* :[font = input; initialization; preserveAspect] *) Protect[Factorization]; (* :[font = input; initialization; preserveAspect; endGroup; endGroup; endGroup] *) EndPackage[] (* ^*)