Re: Working with factors of triangular numbers.
- To: mathgroup at smc.vnet.net
- Subject: [mg78742] Re: [mg78490] Working with factors of triangular numbers.
- From: Andrzej Kozlowski <akoz at mimuw.edu.pl>
- Date: Sun, 8 Jul 2007 06:11:34 -0400 (EDT)
- References: <200707030923.FAA17995@smc.vnet.net> <6D2F6E70-2462-4B69-A617-4DEC322D69BF@mimuw.edu.pl> <93E8C621-E93F-4761-A0FF-205BF84249CD@mimuw.edu.pl> <a851af150707070640g1f6a22e9ue072d4eba5c9262a@mail.gmail.com> <6F7B3048-4C96-48BC-AADF-2A62837DE6D3@mimuw.edu.pl> <9F4DE591-C9FC-4474-A4AA-55BB06222CEB@mimuw.edu.pl>
Just one more remark. I have found that even this relatively slow
program on my slow 1 gigahertz PowerBook can compute
T[8] // Timing
{61.9871, 1413721}
and
Timing[T[9]]
{932.333005, 27331921}
the time complexity of the algorithm is clearly very high, which
suggests that perhaps even a much faster implementation will not be
able to compute many more values in a reasonable time.
Andrzej Kozlowski
On 8 Jul 2007, at 06:21, Andrzej Kozlowski wrote:
> I am still curious how you got these wrong answers using my program
> which is correct and gives the right ones when I run it here, and
> the only hypothesis that comes to my mind that is that it is the
> fault of the program you are using to read e-mail and that the code
> you pasted in was not exactly the same as the one I sent. This has
> been known to happen with some programs. If you are still not
> getting the right answers I can send you a Mathematica notebook.
>
> Andrzej Kozlowski
>
>
> On 7 Jul 2007, at 23:00, Andrzej Kozlowski wrote:
>
>>
>> You must have made some mistake.
>>
>> Let me do it all form the beginning, with Mathematica 6.0 for Mac
>> and fresh kernel:
>>
>> << Combinatorica`
>>
>> FF[n_] := Module[{u = FactorInteger[n], s, k, partialQ, finalQ,
>> space, sp},
>> s = u[[All,2]]; k = Length[u]; sp[m_] := Tuples[Range[0, m], {k}];
>> partialQ[l_List] := And @@ Flatten[{Last[l] == Array[0 & , k] ||
>> !MemberQ[Most[l], Last[l]], Thread[Total[l] <= s - 1]}];
>> finalQ[l_List] := And @@ Flatten[{Last[l] == Array[0 & , k] ||
>> !MemberQ[Most[l], Last[l]], Thread[Total[l] == s - 1]}];
>> space = DeleteCases[sp /@ (s - 1), Alternatives @@
>> IdentityMatrix[k],
>> Infinity]; k + Max[0, Length /@ DeleteCases[Backtrack[space,
>> partialQ,
>> finalQ, All], Array[0 & , k], Infinity]]]
>>
>> T[n_] := Block[{k = 1, $Messages},
>> While[k++; FF[k*((k + 1)/2) - 1] < n, Null]; k*((k + 1)/2)]
>>
>> Map[T, Range[7]]
>> {3, 15, 55, 253, 1081, 13861, 115921}
>>
>> which is what you expected?
>>
>> Andrzej Kozlowski
>>
>>
>>
>> On 7 Jul 2007, at 22:40, Diana Mecum wrote:
>>
>>> Andrzej,
>>>
>>> I appreciate all of the work you have done with my question.
>>>
>>> I tested this latest update, and got
>>>
>>> Map[T, Range[6]]
>>> {3,15,91, 1431, 10011, 218791}
>>>
>>> The expect that the first 6 terms would be:
>>>
>>> {3,15,55,253,1081,13861}
>>>
>>> I used the first's e-mail code for T, and the second code for FF.
>>>
>>> Thanks,
>>>
>>> Diana
>>>
>>> On 7/7/07, Andrzej Kozlowski <akoz at mimuw.edu.pl> wrote: *This
>>> message was transferred with a trial version of CommuniGate(tm) Pro*
>>> I did not intend to work any more on this code, because, as I wrote
>>> earlier, it is certiany possible to implement the same idea much
>>> faster wihtout using the Combinatorica package, but then I noticed a
>>> very blatant inefficiency in the posted code and felt obliged to
>>> correect it. Here is the corrected version of the function FF. The
>>> fucntion T is unchanged.
>>>
>>> Andrzej Kozlowski
>>>
>>> FF[n_] :=
>>> Module[{u = FactorInteger[n], s, k, partialQ, finalQ, space, sp},
>>> s = u[[All, 2]]; k = Length[u]; sp[m_] := Tuples[Range[0, m],
>>> {k}];
>>> partialQ[l_List] :=
>>> And @@
>>> Flatten[{Last[l] == Array[0 &, k] || Not[MemberQ[Most[l], Last
>>> [l]]],
>>> Thread[Total[l] <= s - 1]}];
>>> finalQ[l_List] :=
>>> And @@
>>> Flatten[{Last[l] == Array[0 &, k] || Not[MemberQ[Most[l], Last
>>> [l]]],
>>> Thread[Total[l] == s - 1]}];
>>> space =
>>> DeleteCases[ sp /@ (s - 1), Alternatives @@ (IdentityMatrix[k]),
>>> Infinity];
>>> k + Max[0,
>>> Length /@
>>> DeleteCases[Backtrack[space, partialQ, finalQ, All], Array
>>> [0 &,
>>> k],
>>> Infinity]]]
>>>
>>>
>>> On 6 Jul 2007, at 20:26, Andrzej Kozlowski wrote:
>>>
>>> > *This message was transferred with a trial version of CommuniGate
>>> > (tm) Pro*
>>> > On 3 Jul 2007, at 18:23, Diana wrote:
>>> >
>>> >> Math folks,
>>> >>
>>> >> I first generate a list of triangular numbers:
>>> >>
>>> >> 1, 3, 6, 10, 15, 21, ...
>>> >>
>>> >> and then subtract one from each as:
>>> >>
>>> >> 0, 2, 5, 9, 14, 20, ...
>>> >>
>>> >> I am trying to find the smallest triangular number (minus one)
>>> which
>>> >> can be written as a product of "n" distinct factors, each
>>> factor > 1.
>>> >>
>>> >> For example:
>>> >>
>>> >> a(2) = 15, because 2*7 + 1 = 15.
>>> >> a(3) = 55, because 2*3*9 + 1 = 55.
>>> >>
>>> >> I have worked with Divisors and FactorInteger, but am getting
>>> bogged
>>> >> down with repeated terms. Can someone think of a neat trick to
>>> work
>>> >> this problem?
>>> >>
>>> >> Diana M.
>>> >>
>>> >>
>>> >
>>> > I wil start with a grumble. Unfortunately your problem is not, in
>>> > my judgment, solvable by means of any nice mathematics, because
>>> you
>>> > do not require the factors to be mutually prime, that is, not
>>> to be
>>> > divisible by the same prime. Without that one can't make use of
>>> > uniqueness of prime decomposition and that in this kind of
>>> problems
>>> > generally means that brute force has to be used. (I have a much
>>> > nicer solution of the same problem when the factors are
>>> required to
>>> > be mutually prime)
>>> >
>>> > So now I will present a 'brute force" argument, whose main virtue
>>> > is that it can be much improved (but I will not do so). I will use
>>> > the combinatorica package, which, in Mathematica 6.0 is loaded
>>> like
>>> > this:
>>> >
>>> > << Combinatorica`
>>> >
>>> > I want to make use of the Backtrack function in this package.
>>> (This
>>> > is the main weakness of this approach and the point which can be
>>> > greatly improved). Here is an auxiliary function, which uses
>>> > backtracking:
>>> >
>>> > FF[n_] := Module[{u = FactorInteger[n], s, k, partialQ, finalQ,
>>> > space, sp},
>>> > s = u[[All,2]]; k = Length[u]; sp[m_] := Tuples[Range[0, m],
>>> {k}];
>>> > partialQ[l_List] := And @@ Flatten[
>>> > { !MemberQ[IdentityMatrix[k], Last[l]], Last[l] == Array[0
>>> > & , k] ||
>>> > !MemberQ[Most[l], Last[l]], Thread[Total[l] <= s - 1]}];
>>> > finalQ[l_List] := And @@ Flatten[{ !MemberQ[IdentityMatrix[k],
>>> > Last[l]],
>>> > Last[l] == Array[0 & , k] || !MemberQ[Most[l], Last[l]],
>>> > Thread[Total[l] == s - 1]}]; space = sp /@ (s - 1);
>>> > k + Max[0, Length /@ DeleteCases[Backtrack[space, partialQ,
>>> > finalQ, All],
>>> > Array[0 & , k], Infinity]]]
>>> >
>>> > For any positive integer n this computes the length of the largest
>>> > factorization of n into distinct factors. For example:
>>> >
>>> > FF[2*3*9*11]
>>> > 4
>>> >
>>> > which is obviously right. There is some minor problem in the code
>>> > that causes a Part error message to appear sometimes, without
>>> > however affecting the result:
>>> >
>>> > FF[3]
>>> > Part::partw:Part 2 of {1} does not exist. >>
>>> > Part::partw:Part 2 of ( {
>>> > {{0}}
>>> > } ) does not exist. >>
>>> > Set::partw:Part 2 of {1} does not exist. >>
>>> > 1
>>> >
>>> > However, I don't to spend time on trying to find out the cause of
>>> > this message so on my main program I will simply suppress all
>>> > messages:
>>> >
>>> > So now here is the main function T:
>>> >
>>> > T[n_] := Block[{k = 1, $Messages}, While[k++; FF[k*((k + 1)/2)
>>> - 1]
>>> > < n,
>>> > Null]; k*((k + 1)/2)]
>>> >
>>> > which for a given n looks for the smallest triangular number
>>> with n-
>>> > distinct factors:
>>> >
>>> > Map[T, Range[8]]
>>> > {3, 15, 55, 253, 1081, 13861, 115921, 1413721}
>>> >
>>> > I can't say that this is really fast, but the good news is that it
>>> > certainly could be greatly improved. The Combinatorica general-
>>> > purpose Backtrack function is very slow, and if someone writes a
>>> > custom-made backtracking version suited to the problem at hand and
>>> > compiles it, it will certainly become orders of magnitude faster.
>>> > This has been done on this list in various situations several
>>> > times. Unfortunately I can't spare the time necessary to do
>>> > this. . Writing backtracking programs requires careful procedural
>>> > programming and I am really out of practice in procedural
>>> > programming, but there are several excellent examples in the
>>> > archives written by Fred Simons and Maxim Rytin, and if this is
>>> > important for you, you should either learn to do it yourself by
>>> > studying these programs or persuade one of them to do it for
>>> you ;-)
>>> >
>>> > Andrzej Kozlowski
>>> >
>>> >
>>> > ------------------------------------------
>>> > Your proposition may be good
>>> > But let's have one thing understood --
>>> > Whatever it is, I'm against it!
>>> > And even when you've changed it or condensed it,
>>> > I'm against it.
>>> >
>>> > Professor Quincy Adams Wagstaff
>>> > President of Huxley College
>>>
>>>
>>>
>>>
>>> --
>>> "God made the integers, all else is the work of man."
>>> L. Kronecker, Jahresber. DMV 2, S. 19.
>>
>
- References:
- Working with factors of triangular numbers.
- From: Diana <diana.mecum@gmail.com>
- Working with factors of triangular numbers.