> Why not just convert each arg to Float and use %, and leave the details 
up to Float.__mod__. 

In all honesty, because I have very little idea what I'm doing... =)


I just tried this, but it failed:
def _eval_evalf(self,prec):
    args=[Float(x,prec) for x in self.args]
    return N(args[0] % args[1],prec)


I put the traceback at the bottom of my message to avoid clutter...


>I may not be clear what you're saying, but _eval_evalf only takes two 
>arguments, self and prec. So where would subs be passed to? 


Sorry, I should have been more clear. 


As I read the code in EvalfMixin.evalf, it first tries to call 
evalf(self,prec+4,options). I believe this evalf is in the evalf.py source 
file itself. This version uses evalf_table for dispatch, rather than 
relying on self to have its own implementation. One of the fields of 
'options' is the subs parameter passed to EvalfMixin.evalf


If this version of evalf raises NotImplementedError, then EvalfMixin.evalf 
tries to call self._eval_evalf(prec). It doesn't try to pass the options 
parameter to the _eval_evalf implemented in self, and therefore can't carry 
the subs parameter passed to the EvalfMixin.evalf(self,n,subs,...) call. 


I don't know the reason for the different calling conventions. It appears 
like the dispatch table would best handle classes that can't be extended 
with _eval_evalf, while leaving each class responsible for it's own 
implementation otherwise. The options seem equally useful to both 
implementation routes.  I'm guessing this was an oversight, but I don't 
know the history.


Cheers--
Greg


Here's that traceback:
-------------------------------------------------------------------
    100     def _eval_evalf(self,prec):
--> 101         args=[Float(x,prec) for x in self.args]
    102         return N(args[0] % args[1],prec)
    103 #        return N(mpmath.fmod(*[N(x,prec) for x in self.args]),prec)

/Library/Python/2.7/site-packages/sympy/core/numbers.pyc in __new__(cls, 
num, prec)
    589                 _mpf_ = mpf_norm(_mpf_, prec)
    590         else:
--> 591             _mpf_ = mpmath.mpf(num)._mpf_
    592 
    593         if not num:

/Library/Python/2.7/site-packages/sympy/mpmath/ctx_mp_python.pyc in 
__new__(cls, val, **kwargs)
     75         else:
     76             v = new(cls)
---> 77             v._mpf_ = mpf_pos(cls.mpf_convert_arg(val, prec, 
rounding), prec, rounding)
     78             return v
     79 

/Library/Python/2.7/site-packages/sympy/mpmath/ctx_mp_python.pyc in 
mpf_convert_arg(cls, x, prec, rounding)
     94                 return a
     95             raise ValueError("can only create mpf from zero-width 
interval")
---> 96         raise TypeError("cannot create mpf from " + repr(x))
     97 
     98     @classmethod

TypeError: cannot create mpf from acos(cos(39*pi/115))/(2*pi)







On Wednesday, February 27, 2013 4:55:46 PM UTC-8, Aaron Meurer wrote:
>
> On Wed, Feb 27, 2013 at 5:46 PM, G B <g.c.b....@gmail.com <javascript:>> 
> wrote: 
> > I'm not sure it matters in the end, but it looks like 
> > Mod(Rational(15,7),1).n() works ok too.  I think what's happening is 
> that 
> > when pi isn't in the argument list, it basically gets simplified when 
> the 
> > class construction calls Mod.eval but Mod.eval doesn't know how to 
> simplify 
> > with pi. 
> > 
> > I've patched this into my Mod class: 
> > 
> >     def _eval_evalf(self,prec): 
> >         return N(mpmath.fmod(*[N(x,prec) for x in self.args]),prec) 
>
> You're passing SymPy Floats to the mpmath function, which is not 
> really correct (though I guess it works).  Why not just convert each 
> arg to Float and use %, and leave the details up to Float.__mod__. 
>
> > 
> > It solves my immediate problem, but given how complex the evalf 
> functions 
> > are for everything else, I get the feeling I've done something horribly, 
> > inexcusably naive here.  Am I missing anything? 
> > 
> > I tried Chris' examples and Mod(1e-40,1) returns 0 with my method even 
> > though mpmath.fmod(1e-40,1) returns 1e-40.  It also returns zero if I 
> write 
> > it as Mod(Float(1e-40),S(1)).  I get the proper results with 
> > Mod(1e-40,1,evaluate=False).n(). 
> > 
> > Again, the problem appears to be in Mod.eval, but I'm not sure where. 
> > 
> > The other thing I noticed going through EvalfMixin.evalf is that the 
> options 
> > parameter isn't passed to self._eval_evalf, which means that subs 
> parameters 
> > won't get passed unless _eval_evalf is in the evalf_table.  I don't know 
> if 
> > this was intentional or an oversight. 
>
> I may not be clear what you're saying, but _eval_evalf only takes two 
> arguments, self and prec.  So where would subs be passed to? 
>
> Aaron Meurer 
>
> > 
> > Cheers-- 
> >  Greg 
> > 
> > 
> > 
> > On Wednesday, February 27, 2013 3:40:57 PM UTC-8, Aaron Meurer wrote: 
> >> 
> >> On Wed, Feb 27, 2013 at 1:41 PM, Chris Smith <smi...@gmail.com> wrote: 
> >> >> It looks like Mod doesn't implement evalf at all, and it doesn't 
> work 
> >> >> automatically (that only happens if the function name is the same as 
> >> >> the mpmath function name).  It should be easy.  Just evaluate the 
> >> >> arguments, and then take the mod of them. 
> >> > 
> >> > In general this is not going to work: 
> >> > 
> >> > ``` 
> >> >>>> Mod(1e-30,3) 
> >> > 1.00000000000000e-30 
> >> >>>> Mod(1e-40,3) 
> >> > 0.0 
> >> > ``` 
> >> > 
> >> > whereas 
> >> > 
> >> > ``` 
> >> >>>> 1e-40 % 3 
> >> > 9.9999999999999993e-41 
> >> > ``` 
> >> 
> >> Isn't that just a roundoff error. If you use Float, you get 1e-40. 
> >> 
> >> Aaron Meurer 
> >> 
> >> > 
> >> > Something like this might work when a > b (when a < b the answer is 
> >> > `a`): 
> >> > 
> >> > ``` 
> >> >>>> a,b=pi**3,S(3) 
> >> >>>> (a - round(a/b)*b).n() 
> >> > 1.00627668029982 
> >> >>>> a.n() % b.n() 
> >> > 1.00627668029982 
> >> > ``` 
> >> > 
> >> > -- 
> >> > You received this message because you are subscribed to the Google 
> >> > Groups "sympy" group. 
> >> > To unsubscribe from this group and stop receiving emails from it, 
> send 
> >> > an email to sympy+un...@googlegroups.com. 
> >> > To post to this group, send email to sy...@googlegroups.com. 
> >> > Visit this group at http://groups.google.com/group/sympy?hl=en. 
> >> > For more options, visit https://groups.google.com/groups/opt_out. 
> >> > 
> >> > 
> > 
> > -- 
> > You received this message because you are subscribed to the Google 
> Groups 
> > "sympy" group. 
> > To unsubscribe from this group and stop receiving emails from it, send 
> an 
> > email to sympy+un...@googlegroups.com <javascript:>. 
> > To post to this group, send email to sy...@googlegroups.com<javascript:>. 
>
> > Visit this group at http://groups.google.com/group/sympy?hl=en. 
> > For more options, visit https://groups.google.com/groups/opt_out. 
> > 
> > 
>

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sympy+unsubscr...@googlegroups.com.
To post to this group, send email to sympy@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to