You can use the fact that rules apply in the order in which they appear:
Options[f] = Join[{WorkingPrecision -> 10}, Options[NDSolve]];
f[opts : OptionsPattern[]] := NDSolve[..., FilterRules[Join[{opts},
Options[NDSolve]], Options[NDSolve]]]
The same principle can also be used to specify default parameters so that OptionValue
will automatically fall back on the defaults of NDSolve
unless otherwise specified. Consider this example:
Options[f] = {a -> 1, a -> 2, b -> 3};
f[opts : OptionsPattern[]] := OptionValue[a]
f[]
1
It shows that default values are considered in the order in which they appear, i.e. the default value for a
in this function is 1 and not 2.
Similarly, you can also write
Options[f] = Join[{WorkingPrecision -> 10}, Options[NDSolve]];
f[opts : OptionsPattern[]] := OptionValue[WorkingPrecision]
f[]
10
and be assured that whatever you specify overrides whatever NDSolve
used.
And if we combine the two approaches we get to this:
Options[f] = Join[{WorkingPrecision -> 10}, Options[NDSolve]];
f[opts : OptionsPattern[]] := NDSolve[..., FilterRules[Join[{opts},
Options[f]], Options[NDSolve]]]
which will take into account default options of NDSolve
that you have overridden.
These patterns are probably used quite extensively in the built-in functions. The plotting functions also take the options from Graphics
for example, I imagine this is how that is done.