On 31 Aug 2006, at 09:38, Arkadiusz Majka wrote:
> Dear All,
>
> Thank all of you for your help regarding my "generalized fold list
> problem", that sounds
>
>>> I have two list
>>
>> list1={a,b,c,d,e}
>> list2={3,2,5,1,6}
>>
>> and I want to apply a modified version of FoldList to list1 in the
>> following way: list2 indicates that element a appears only 3 times
>> (if
>> space enough) beginning from the beginning of the list , element b
>> appears 2 times, c - 5 times , etc.
>>
>> So the output should be
>>
>> GeneralizedFoldList[list1,list2]={a,a+b,a+b+c,c+d,c+e}
>>
>>
>
> Now, I still need your help. What I want to do now, and what I have
> problem with, is to add a constraint to the algorithm, i.e every
> element in my GeneralizedFoldList must be less than one.
> The following example says what to do if it is not.
>
> Lets take two lists
>
> list1={0.9,0.8,0.7}
> list2={3,3,3}
>
> All your algorithms use PadRight (you pad 0's). So the following
> matrix
> is built
>
> {{0.9, 0.9, 0.9, 0, 0}, {0, 0.8, 0.8, 0.8, 0}, {0, 0, 0.7, 0.7, 0.7}}
>
> and we add elements along colums and obtain {0.9, 1.7, 2.4, 1.5, 0.7}
>
> The first element is less than 1 so it's ok. The second is > 1 what I
> need to avoid. I want to avoid it by shifting the nonzero elements of
> the second and third row of above matrix of two positions:
> {0,0,0,0.8,0.8,0.8,0}, {0,0,0,0,0.7,0.7,0.7}.
>
> I go on with suming along columns and discover that everything is fine
> until I have to add 0.8 and 0.7 what is >1. So I repeat the procedure
> by shfting hte third row of the number of position that is needed to
> ensure that my sum is <1.
>
> Finally I obtain {{0.9, 0.9, 0.9, 0, 0, 0, 0, 0,
> 0},{0,0,0,0.8,0.8,0.8,0,0,0},{0,0,0,0,0,0,0.7,0.7,0.7}}
> and Plus@@% is what I desire.
>
> Thanks in advance! I hope you will manage :)
>
> Arek
>
Here is a (not very pretty) code that should do what you want
starting with a matrix of the above kind:
GF[P_]:=Module[{M=P},Do[M = NestWhile[
Join[(PadRight[#1, Length[#1] + 1] & ) /@
Take[#1, s], (PadLeft[#1, Length[#1] + 1] & ) /@
Take[#1, s - Dimensions[#1][[1]]]] & , M,
!And @@ Thread[Total[#1[[All,Range[Length[
Flatten[Split[#1[[s]]] /. {l___,
{(0)..}} :> {l}]]]]]] < 1] & ],
{s, Dimensions[M][[1]]}]; M]
Let's verify that it works. First, starting with your original case:
In[8]:=
M={{0.9,0.9,0.9,0,0},{0,0.8,0.8,0.8,0},{0,0,0.7,0.7,0.7}};
In[9]:=
GF[M]//InputForm
Out[9]//InputForm=
{{0.9, 0.9, 0.9, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0.8, 0.8, 0.8, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0.7, 0.7, 0.7}}
Now let's change M somewhat:
In[10]:=
M={{0.9,0.9,0.1,0,0},{0,0.1,0.8,0.3,0},{0,0,0.7,0.9,0.7}};
In[11]:=
GF[M]//InputForm
Out[11]//InputForm=
{{0.9, 0.9, 0.1, 0, 0, 0, 0, 0}, {0, 0, 0.1, 0.8, 0.3, 0,
0, 0}, {0, 0, 0, 0, 0, 0.7, 0.9, 0.7}}
So you only need to combine this with your favourite code from part 1.
(PS. In answering part 1 I obviously misunderstood your question, but
I think that was mainly because I do not think your function is in
any way a "generalisation of Fold", or even of Fold
[Plus,element,list]. As far as I can see it does not really perform
any kind of "folding".
Andrzej Kozlowski