On Mon, Feb 3, 2014 at 12:41 AM, G B <[email protected]> wrote: > On Sunday, February 2, 2014 6:21:45 PM UTC-8, Aaron Meurer wrote: >> >> A few comments: >> >> - You should wrap the float in a string, so that you don't lose >> precision from Python's float. > > > Thanks. > >> >> - Why have you made __abs__ a staticmethod? Also, SymPy's Abs uses >> _eval_Abs. But you won't need it anyway, because you've defined it to >> be positive. > > > The only worked examples I could find are in sympy.core.numbers and both Pi > and Exp1 have an __abs__ staticmethod.
Apparently there are some poor coding practices here. Anyway, the worst thing that will happen here is that it will mess up subclasses (e.g., if you try to subclass pi to change some behavior of it, abs(yoursubclass) would give the original pi. We have a lot of this actually (https://code.google.com/p/sympy/issues/detail?id=3652). But for pi ane Exp1, I'm not really sure if they can be subclassed in the first place, as I'm not sure if the Singleton metaclass supports it. I haven't tried it, though, so maybe it does. > >> >> - To get printing, you need to define the printing methods. See >> http://docs.sympy.org/latest/modules/printing.html. You need to define >> the "printmethod" for each printer that you care about. The most >> common ones are the string printer, the ASCII pretty printer, the >> Unicode pretty printer, and the LaTeX printer. If you want it to work >> with lambdify() you'll need to use the LambdaPrinter. If you want it >> to work with the code generation you'll need to define the relevant >> printer for the languages you are interested in. > > > Ok, I think I've go this mostly working. The main difference is that > print(kB) returns the float value while print(pi) returns the string "pi". > This was > necessary to get LambdaPrinter to work, because LambdaPrinter looks to use > the _sympystr method. Pi is happy, presumably because numpy > has a pi value, so the string is interpreted later in the chain. Pretty > print and latex do as I'd like, so that's good enough for now. Hmm. I don't know why LambdaPrinter uses the same method as StrPrinter. I'd consider that to be a bug. It's fine if it falls back to the str printer, but it should have its own print method as well. > >> >> - Making it a Singleton is not required. This is done in SymPy for >> efficiency purposes. Neither is setting __slots__ to []. They >> shouldn't hurt either way, though. If you want your code to work in >> Python 3 you'll need to use with_metaclass. >> - Defining __int__ shouldn't be necessary. If it is, that's a bug, >> because the superclass should have that defined in such a way that it >> figures it out automatically from the evalf() value. > > > Again, I just mimicked what I saw for pi and E. (I'm still using 0.72, if > that makes a difference) That is an old version, but it's still there in the current version. I guess it's for efficiency purposes; it's faster to just have the value 3 precomputed (e.g., for int(pi)), then to evalf it each time. > > > What I have now is: > > class BoltzmannConstant(NumberSymbol): > > is_real = True > is_positive = True > is_negative = False > is_irrational = None > > val='1.3806488e-23' > > > def _eval_evalf(self,prec): > return N(self.val,prec) > > def __str__(self,*args): > return 'kB' > > def _sympystr(self,*args): > return self.val > > def _latex(self,*args): > return 'k_{B}' > > kB = BoltzmannConstant() > > > I took a stab at writing code to simplify the creation of these types of > constants, but I don't completely understand the architecture. It's not > clear to me why values such as Pi are classes derived from NumberSymbol > rather than instances of NumberSymbol. It's because of the singleton metaclass. It automatically creates a (unique) instance of each class that has it. This wouldn't work if there were only one class, at least not the way it's currently designed. Anyway, it makes more sense to have them be their own classes, because they have their own definition of each of the various methods, like _eval_evalf or _eval_is_positive or __int__. So probably if there were something to make this easier it would itself be a metaclass or a class factory of some kind. I can't think of anything that would go wrong if it weren't and everything was just instance of the same class like you suggested, though. Aaron Meurer > > Thanks for the help-- > Greg > > > >> >> Aaron Meurer >> >> On Sun, Feb 2, 2014 at 8:12 PM, G B <[email protected]> wrote: >> > Ok, I tried this and it seems to behave well at a basic level: >> > >> > from sympy.core.singleton import Singleton >> > class BoltzmannConstant(NumberSymbol): >> > __metaclass__ = Singleton >> > >> > >> > is_real = True >> > is_positive = True >> > is_negative = False >> > is_irrational = None >> > >> > >> > __slots__ = [] >> > >> > >> > @staticmethod >> > def __abs__(): >> > return S.BoltzmannConstant >> > >> > >> > def __int__(self): >> > return 0 >> > >> > >> > def _eval_evalf(self,prec): >> > return N(1.3806488e-23,prec) >> > >> > kB = S.BoltzmannConstant >> > >> > >> > Does that look like a reasonable implementation? >> > >> > How would I associate the symbol "k_B" with this Singleton? Right now >> > when >> > I enter kB, it displays as 'BoltzmannConstant()' (whereas pi somehow >> > knows >> > to display as \pi). >> > >> > >> > >> > On Sunday, February 2, 2014 5:40:21 PM UTC-8, Aaron Meurer wrote: >> >> >> >> I don't think pi and Exp1 are good examples because they are already >> >> implemented in mpmath, and can be computed to an arbitrary number of >> >> digits. That's what the mpf stuff is doing. For your case, I think you >> >> just need to define _eval_evalf(self, prec), which should return a >> >> Float to prec digits. >> >> >> >> _sage_ is just to convert the objects to Sage equivalents. If you >> >> don't intend for you code to ever be used within Sage you don't need >> >> to worry about it. >> >> >> >> Aaron Meurer >> >> >> >> On Sun, Feb 2, 2014 at 7:12 PM, G B <[email protected]> wrote: >> >> > I'd like to set up values that display as symbols but evaluate to >> >> > numbers >> >> > when called with .n(). I think this is similar to how pi and E are >> >> > handled. >> >> > In my case it's constants such as the speed of light, and Boltzmann's >> >> > constant. When I look at the symbolic representation, I'd like to >> >> > see >> >> > these >> >> > values represented as symbols (c, k_B), but when I evaluate I'd like >> >> > their >> >> > true value used without the need for explicit substitution. >> >> > >> >> > Is there an easy way to set up such values? >> >> > >> >> > Looking through the source, I found Pi and Exp1 defined in >> >> > sympy.core.numbers-- and it looks like each is a custom class. Is >> >> > there >> >> > a >> >> > trick to setting up _as_mpf_val and approximation_interval for >> >> > physical >> >> > constants such as these? Does _sage_ need to be implemented if I'm >> >> > not >> >> > running within Sage? >> >> > >> >> > Thanks-- >> >> > Greg >> >> > >> >> > -- >> >> > 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 [email protected]. >> >> > To post to this group, send email to [email protected]. >> >> > Visit this group at http://groups.google.com/group/sympy. >> >> > 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 [email protected]. >> > To post to this group, send email to [email protected]. >> > Visit this group at http://groups.google.com/group/sympy. >> > 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 [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/sympy. > 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 [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/sympy. For more options, visit https://groups.google.com/groups/opt_out.
