Re: Flattening lists

2009-02-05 Thread jason-sage

mk wrote:

Hello everybody,

Any better solution than this?

def flatten(x):
res = []
for el in x:
if isinstance(el,list):
res.extend(flatten(el))
else:
res.append(el)
return res

a = [1, 2, 3, [4, 5, 6], [[7, 8], [9, 10]]]
print flatten(a)


It depends on what you mean by better.  More features?  Here is the 
function from Sage (http://www.sagemath.org), which is a modified 
version of a more standard implementation to give a max_level argument.


The first few lines of documentation:

def flatten(in_list, ltypes=(list, tuple), max_level=sys.maxint):
  
  Flattens a nested list.

  INPUT:
  in_list -- a list or tuple
  ltypes -- optional list of particular types to flatten
  max_level -- the maximum level to flatten

  OUTPUT:
  a flat list of the entries of in_list

(lots of examples follow this documentation)

The implementation:  
http://www.sagemath.org/hg/sage-main/file/b0aa7ef45b3c/sage/misc/flatten.py



Jason

--
http://mail.python.org/mailman/listinfo/python-list


Re: Mathematica 7 compares to other languages

2008-12-04 Thread jason-sage

Xah Lee wrote:

alright, here's my improved code, pasted near the bottom.

let me say a few things about Jon's code.

If we rate that piece of mathematica code on the level of: Beginner
Mathematica programer, Intermediate, Advanced, where Beginner is
someone who just learned tried to program Mathematica no more than 6
months, then that piece of code is Beginner level.

Here's some basic analysis and explanation.

The program has these main functions:

• RaySphere
• Intersect
• RayTrace
• Create
• Main

The Main calls Create then feed it to RayTrace.
Create calls itself recursively, and basically returns a long list of
a repeating element, each of the element differ in their parameter.

RayTrace calls Intersect 2 times. Intersect has 2 forms, one of them
calls itself recursively. Both forms calls RaySphere once.

So, the core loop is with the Intersect function and RaySphere. Some
99.99% of time are spent there.

--

I didn't realize until after a hour, that if Jon simply give numerical
arguments to Main and Create, the result timing by a factor of 0.3 of
original. What a incredible sloppiness! and he intended this to show
Mathematica speed with this code?

The Main[] function calls Create. The create has 3 parameters: level,
c, and r. The level is a integer for the recursive level of
raytracing . The c is a vector for sphere center i presume. The r is
radius of the sphere. His input has c and r as integers, and this in
Mathematica means computation with exact arithmetics (and automatic
kicks into infinite precision if necessary). Changing c and r to float
immediately reduced the timing to 0.3 of original.

--
now, back to the core loop.

The RaySphere function contain codes that does symbolic computation by
calling Im, which is the imaginary part of a complex number!! and if
so, it returns the symbol Infinity! The possible result of Infinity is
significant because it is used in Intersect to do a numerical
comparison in a If statement. So, here in these deep loops,
Mathematica's symbolic computation is used for numerical purposes!

So, first optimization at the superficial code form level is to get
rid of this symbolic computation.

Instead of checking whethere his “disc = Sqrt[b^2 - v.v + r^2]” has
imaginary part, one simply check whether the argument to sqrt is
negative.

after getting rid of the symbolic computation, i made the RaySphere
function to be a Compiled function.

I stopped my optimization at this step.

The above are some _fundamental_ things any dummy who claims to code
Mathematica for speed should know. Jon has written a time series
Mathematica package that he's selling commercially. So, either he got
very sloppy with this Mathematica code, or he intentionally made it
look bad, or that his Mathematica skill is truely beginner level. Yet
he dares to talk bullshit in this thread.

Besides the above basic things, there are several aspects that his
code can improve in speed. For example, he used pattern matching to do
core loops.
e.g. Intersect[o_, d_][{lambda_, n_}, Bound[c_, r_, s_]]

any Mathematica expert knows that this is something you don't want to
do if it is used in a core loop. Instead of pattern matching, one can
change the form to Function and it'll speed up.

Also, he used “Block”, which is designed for local variables and the
scope is dynamic scope. However the local vars used in this are local
constants. A proper code would use “With” instead. (in lisp, this is
various let, let*. Lispers here can imagine how lousy the code is
now.)

Here's a improved code. The timing of this code is about 0.2 of the
original. Also, optimization is purely based on code doodling. That
is, i do not know what his code is doing, i do not have experience in
writing a ray tracer. All i did is eyeballing his code flow, and
improved the form.

norm=Function[#/Sqrt@(Plus@@(#^2))];
delta=Sqrt[$MachineEpsilon];
myInfinity=1.;

Clear[RaySphere];
RaySphere = Compile[{o1, o2, o3, d1, d2, d3, c1, c2, c3, r},
Block[{v = {c1 - o1, c2 - o2, c3 - o3},
  b = d1*(c1 - o1) + d2*(c2 - o2) + d3*(c3 - o3),
  discriminant = -(c1 - o1)^2 - (c2 - o2)^2 +
(d1*(c1 - o1) + d2*(c2 - o2) + d3*(c3 - o3))^2 -
(c3 - o3)^2 + r^2, disc, t1, t2},
 If[discriminant  0., myInfinity,
  disc = Sqrt[discriminant]; If[(t1 = b - disc)  0.,
t1, If[(t2 = b + disc) = 0., myInfinity, t2];

Remove[Intersect];
Intersect[{o1_,o2_,o3_},{d1_,d2_,d3_}][{lambda_,n_},Sphere
[{c1_,c2_,c3_},r_]]:=
  Block[{lambda2=RaySphere[o1,o2,o3,d1,d2,d3,c1,c2,c3,r]},
If[lambda2≥lambda,{lambda,n},{lambda2,
norm[{o1,o2,o3}+lambda2 *{d1,d2,d3}-{c1,c2,c3}]}]]

Intersect[{o1_,o2_,o3_},{d1_,d2_,d3_}][{lambda_,n_},
Bound[{c1_,c2_,c3_},r_,s_]]:=
  Block[{lambda2=RaySphere[o1,o2,o3,d1,d2,d3,c1,c2,c3,r]},
If[lambda2≥lambda,{lambda,n},
  Fold[Intersect[{o1,o2,o3},{d1,d2,d3}],{lambda,n},s]]]

Clear[neglight,nohit]
[EMAIL PROTECTED],3,-2}];
nohit={myInfinity,{0.,0.,0.}};


Re: Mathematica 7 compares to other languages

2008-12-03 Thread jason-sage

[EMAIL PROTECTED] wrote:


So when you need an algorithm, you can often find it already inside,
for example in the large Combinatorics package. So it has WAY more
batteries included, compared to Python. I'd like to see something as
complete as that Combinatorics package in Python.
  



Sage (http://www.sagemath.org/, based on Python) already has some pretty 
powerful and comprehensive combinatorics functionality (including lots 
of things that Mma doesn't have).  What's more, one of the most 
comprehensive combinatorics libraries out there, MuPAD combinat, is 
currently in the process of switching to Sage (and becoming the 
Sage-combinat project).  See http://wiki.sagemath.org/combinat/.


If you are interested in graph theory, then you might be interested in 
the comparison to the Combinatorica package at 
http://wiki.sagemath.org/CombinatoricaCompare .  This page is a little 
old, but it gives you an idea of how things compare.


Jason


--
http://mail.python.org/mailman/listinfo/python-list


clearing all warning module caches in a session

2008-07-26 Thread jason-sage

Hi all,

I just started using the warnings module in Python 2.5.2.  When I 
trigger a warning using the default warning options, an entry is created 
in a module-level cache so that the warning is ignored in the future.  
However, I don't see an easy way to clear or invalidate these 
module-level caches of previously triggered warnings.  That means that 
if I ever have a warning triggered with a once or a default warning 
level or filter, I can never see that warning again until I restart 
python (or figure out what module contains the cache and delete it 
manually).


I thought resetwarnings would invalidate the module-level caches, so 
that I could trigger a once warning, then do resetwarnings() and make 
the default an always action and see my warning displayed again.  At 
least, the name seems to indicate that all *warnings* would be reset, 
not just the filter list.  But apparently resetwarnings() just clears 
the filter list, which is helpful, but doesn't do anything for the 
already-cached warnings.


A very small change in the code would make this possible.  Instead of 
making the value of the warnings module-level cache just 1, make it an 
integer which is incremented each time resetwarnings() is called.  That 
way calling resetwarnings() can invalidate the cache (i.e., the warnings 
processing would ignore the cache record if the value wasn't the current 
integer).


Again, the question is: is there an easy way to invalidate all the 
module-level caches of warnings so that the entire warning system is 
truly reset?


Thanks,

Jason

--
http://mail.python.org/mailman/listinfo/python-list