Re: Creating Objects
- To: mathgroup at smc.vnet.net
- Subject: [mg122332] Re: Creating Objects
- From: A Retey <awnl at gmx-topmail.de>
- Date: Tue, 25 Oct 2011 06:18:48 -0400 (EDT)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
- References: <j80qhd$afd$1@smc.vnet.net>
Hi, > Does anyone know how to create Objects in Mathematica, such as those > produced by LinearModelFit or NDSolve`ProcessEquations? For instance, > let data be a set of statistical data. Then data["Mean"] would give > me the mean, data["Values"] would return me the original values, > etc. > > Here is an example from LinearModelFit: > > data = {{0, 1}, {1, 0}, {3, 2}, {5, 4}}; lm = LinearModelFit[data, x, > x]; Save["Model.txt",lm]; > > The saved output is > > lm = FittedModel[{"Linear", {0.18644067796610198, > 0.6949152542372881}, {{x}, {1, x}}, {0, 0}}, {{1., 1., 1., 1.}}, {{0, > 1}, {1, 0}, {3, 2}, {5, 4}}, {{1., 0.}, {1., 1.}, {1., 3.}, {1., > 5.}}, Function[Null, Internal`LocalizedBlock[{x}, #1], {HoldAll}]] > > Which has, basically, only the data and the fitted parameters. > Nonetheless, by doing lm["FitResiduals"] it computes the residuals > for me. > > In my impression, this is as close as one can get to object-oriented > programming in Mathematica, and would be a quite useful feature to > use. I haven't found any documentation on this. Anyone knowns? It is a common programming pattern in Mathematica to define a "data type" by using a special head and then write functions that work with that kind of data type by pattern matching for that head, e.g.: mean[ts_timeseries]:=Mean[timeseries[[1,All,2]]] ts = timeseries[{{0, 1}, {1, 2}, {2, 4}}] mean[ts] You can create the behavior you were asking for by just defining corresponding patterns for such a "data type", e.g.: timeseries[data_]["Mean"] := Mean[data[[All, 2]]] ts = timeseries[{{0, 1}, {1, 2}, {2, 4}}] ts@"Mean" Using patterns as shown above to access certain "properties" of that kind of data type is then just syntactic sugar. Using Strings instead of symbols is convenient when working with name spaces (Contexts) because it avoids shadowing problems with common identifiers. If you wonder where those rules are stored, that is the SubValues: SubValues[timeseries] which are unfortunately only documented very sparse. You will also find that for the built in functions you don't find these rules in SubValues: SubValues[FittedModel] but that is also true for the more often used DownValues, which are also not shown for built in symbols. I can't say whether that means that there is necessarily more than such definitions "behind the scene" for the built in symbols like FittedModel. If you are thinking about using that approach you might also want to look at Format, which will let you define a convenient formatting for your data type, which is especially interesting when working with larger datasets which you don't want to be shown within a notebook by accident, e.g.: Format[timeseries[data___]] := Interpretation["timeseries"["<>"], timeseries[data]] or even: Format[timeseries[data___]] := Interpretation[ "timeseries"[ListPlot[data, ImageSize -> Tiny, Frame -> True, FrameTicks -> False]], timeseries[data]] To look at the underlying data, you will not need to save that to a file, looking at the InputForm or FullForm is usually good enough: data = {{0, 1}, {1, 0}, {3, 2}, {5, 4}}; LinearModelFit[data, x, x] // InputForm hth, albert