       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

```

• Prev by Date: Re: runs slowly?
• Next by Date: Re: Creating Objects
• Previous by thread: Re: Creating Objects
• Next by thread: AbsoluteTime[] runs slowly?