Prev: Any idea how to parallelize this small code construct
Next: More flexibility in placement of ChartLegend
From: Vincent on 8 Jul 2010 03:12 Is there an easy way to get Mathematica to interpret custom code when a FittedModel is called with a custom argument, for example if I have modelfit = NonlinearModelFit[...] modelfit ["EstimatedPower"] which would then call my own code using the modelfit object to compute something? I know that it's trivial to achieve the same functionality just calling the function on the variable, but I rather like the object orientet like syntax of adding my own figures to the FittedModel object.
From: Darren Glosemeyer on 8 Jul 2010 20:33 Vincent wrote: > Is there an easy way to get Mathematica to interpret custom code when > a FittedModel is called with a custom argument, for example if I have > > modelfit = NonlinearModelFit[...] > > modelfit ["EstimatedPower"] > > which would then call my own code using the modelfit object to compute > something? > I know that it's trivial to achieve the same functionality just > calling the function on the variable, but I rather like the object > orientet like syntax of adding my own figures to the FittedModel > object. > > There currently isn't a mechanism in place for this. A possibility if you really want an object oriented approach could be to define a new operator that will get properties via FittedModel if possible and from other definitions when added. In[1]:= nlm = NonlinearModelFit[Range[10]^2, b*Exp[a*x], {a, b}, x]; (* get property from built-in code for defined properties *) In[2]:= myModelProperties[model : FittedModel[{"Nonlinear", __}, __]][prop_] := model[prop] /; MemberQ[model["Properties"], prop] (* give the definition for a new property *) In[3]:= myModelProperties[model : FittedModel[{"Nonlinear", __}, __]][ "SinVariance"] := Sin[model["EstimatedVariance"]] (* define a construct for lists of properties *) In[4]:= myModelProperties[model : FittedModel[{"Nonlinear", __}, __]][ vals : {_String ...}] := Map[myModelProperties[model], vals] (* this is our new object *) In[5]:= op = myModelProperties[nlm]; (* get single newly defined and pre-existing properties and get both in a list at once *) In[6]:= op["SinVariance"] Out[6]= 0.618074 In[7]:= op["BestFit"] 0.288603 x Out[7]= 5.86625 E In[8]:= op[{"SinVariance", "BestFit"}] 0.288603 x Out[8]= {0.618074, 5.86625 E } For lists of properties, the code above may be slower than the built-in FittedModel property code because the FittedModel code re-uses shared intermediate results while the code above does not. Darren Glosemeyer Wolfram Research
From: Vincent on 10 Jul 2010 03:59
On Jul 9, 2:33 am, Darren Glosemeyer <darr...(a)wolfram.com> wrote: > Vincent wrote: > > Is there an easy way to get Mathematica to interpret custom code when > > a FittedModel is called with a custom argument, for example if I have > > > modelfit = NonlinearModelFit[...] > > > modelfit ["EstimatedPower"] > > > which would then call my own code using the modelfit object to compute > > something? > > I know that it's trivial to achieve the same functionality just > > calling the function on the variable, but I rather like the object > > orientet like syntax of adding my own figures to the FittedModel > > object. > > There currently isn't a mechanism in place for this. A possibility if > you really want an object oriented approach could be to define a new > operator that will get properties via FittedModel if possible and from > other definitions when added. > > In[1]:= nlm = NonlinearModelFit[Range[10]^2, b*Exp[a*x], {a, b}, x]; > > (* get property from built-in code for defined properties *) > In[2]:= myModelProperties[model : FittedModel[{"Nonlinear", __}, > __]][prop_] := > model[prop] /; MemberQ[model["Properties"], prop] > > (* give the definition for a new property *) > In[3]:= myModelProperties[model : FittedModel[{"Nonlinear", __}, __]][ > "SinVariance"] := Sin[model["EstimatedVariance"]] > > (* define a construct for lists of properties *) > In[4]:= myModelProperties[model : FittedModel[{"Nonlinear", __}, __]][ > vals : {_String ...}] := Map[myModelProperties[mode= l], vals] > > (* this is our new object *) > In[5]:= op = myModelProperties[nlm]; > > (* get single newly defined and pre-existing properties and get both in > a list at once *) > In[6]:= op["SinVariance"] > > Out[6]= 0.618074 > > In[7]:= op["BestFit"] > > 0.288603 x > Out[7]= 5.86625 E > > In[8]:= op[{"SinVariance", "BestFit"}] > > 0.288603 x > Out[8]= {0.618074, 5.86625 E } > > For lists of properties, the code above may be slower than the built-in > FittedModel property code because the FittedModel code re-uses shared > intermediate results while the code above does not. > > Darren Glosemeyer > Wolfram Research Thank you very much for your reply, I found it very helpful, and the idea of making new classes when you want to extend the properties of a current class seems very much in line with object oriented thinking. While trying to solve the problem on my own i came by a different method, which however did not allow list of properties. By unprotecting string and making a definition for it, you get something like what I wanted ClearAttributes[String,Protected] FittedModule[a__]["EstimatedPower"]^:=findpower[fittedModule[a]] SetAttributes[String,Protected] Now I'm thinking that this is very bad, since Mathematica now makes an additional check everytime a sting is input to a function, is this correct? I was thinking you could get by this simply considering EstimatedPower a symbol, which allows you to just call the FittedModels with syntax like mld[EstimatedPower], which is almost the same except for the quotes. This would only be checked specifically when the EstimatedPower property is requested right? SetAttibutes[EstimatedPower,Protected] FittedModule[a__][EstimatedPower]^:=findpower[fittedModule[a]] I'm going to go with a solution like what you posted, however if you or anyone else would care to comment on these two examples I would be very happy to see if my understanding of up/downvalues is way off. |