flatten() extended functionality



Hi!

I think this is a great idea (negative arguments - very neat).  
Implementation is a bit more complex though than the usual case.

Adding a 'flatten_at' is not too hard probably. It can be a new  
function or it can be the existing (I would prefer that) 'flatten'  
with a new calling form:
flatten( mylist, [2]); to perform flattening only at level 2 or even
flatten( mylist, [2,4]); to flatten only levels 2 and 4.
I can be done (my lisp skill aren't exactly great though - the  
resulting code would probably be too C-like).

I would like to see all these 'extensions' to flatten() in Maxima. If  
noone is voulenteering for extending flatten in such ways, then maybe  
I can try.

Regards,
Ziga Lenarcic

On 15. May, 2009, at 1:14 PM, reyssat wrote:

> Hello,
>
> It might be useful to flatten "inside first"
>
> aa:[[a,b], [[c]], d, [[h],[[d],s]]];
>
> flatten(aa,-3) -->  [[a,b], [[c]], d, [[h],[d,s]]]
> flatten(aa,-2) -->  [[a,b], [c], d, [h,d,s]]
> flatten(aa,-1) -->  [a,b, c, d, h,d,s]
>
> In usual situations (homogenous levels), "map(flatten())" will do  
> the job but maybe inefficiently.
>
> One can also imagine some mixed cases (flatten the "deep but not  
> too deep" objects), but it is probably too rarely useful do spend  
> too much work on this.
>
> Eric Reyssat
>
>
>
> ?iga Lenar?i? a ?crit :
>> Hi!
>>
>> I've sent this email to Starvos (since he is the copyright holder  
>> of  nset.lisp) a couple of days ago, but I haven't gotten any  
>> response.  Therefore I'm sending this on maxima mailing list.
>>
>> I've modified $flatten in nset.lisp:
>> --------------------------
>> (defun flattenl-op (e op num)
>>    (mapcan #'(lambda (e)
>> 	        (cond ((or (= num 0) (mapatom e) (not (alike1 (mop e) op)))
>> 	  	     (list e))
>> 	  	    (t (flattenl-op (margs e) op (1- num)))))
>> 	    e))
>>
>> (defun $flatten (e &optional (num nil))
>>    (unless (and (not (null num)) (integerp num) (> num -1))
>>      (merror "flatten: Second argument must be a non-negative   
>> integer: ~M" num))
>>    (when (null num) (setf num -1))
>>    (cond ((or (= num 0) (specrepp e) (mapatom e)) e)
>>      (t (mcons-op-args (mop e) (flattenl-op (margs e) (mop e)  
>> num)))))
>> -------------------------
>>
>> It works as before for flatten(expr). For 'flatten(expr, num)'  
>> the  result is, that flatten 'flattens' 'num' times:
>>
>> %i84: aa:[[a,b], [[c]], d, [[h],[[d],s]]];
>> %o84: [[a,b],[[c]],d,[[h],[[d],s]]]
>>
>> %i134: flatten(aa,1);
>> %o134: [a,b,[c],d,[h],[[d],s]]
>>
>> %i135: flatten(aa,2);
>> %o135: [a,b,c,d,h,[d],s]
>>
>> %i136: flatten(aa,3);
>> %o136: [a,b,c,d,h,d,s]
>> ..
>>
>> My lisp sucks (feel free to rewrite), I know, but what do you  
>> think  about the functionality? This would breach the gap between  
>> table and  create_list output, as
>> flatten( table(i+j,[i,3],[j,3]) , 1) == create_list(i+j, i,1,3, j, 
>> 1,3).
>>
>> Also such flatten functionality can come in handy in many places  
>> when  working with lists of perhaps coordinates [x,y,z] and you  
>> don't want  to flatten out the whole list all together...
>>
>> I can include this to CVS if I get developer access... Otherwise  
>> it  would be nice if someone did it instead of me.
>>
>> Regards,
>> Ziga Lenarcic
>>
>>
>> _______________________________________________
>> Maxima mailing list
>> Maxima at math.utexas.edu
>> http://www.math.utexas.edu/mailman/listinfo/maxima
>>
>>
>