2

I often need to extract to restrict value lists to sublists, ie if vals gives values of vars={x1,x2,x3,x4}, and I need values of svars={x2,x4} I do restrict[list,vars,svars] where

restrict[vars_, svars_, vals_] := 
 Extract[vals, Flatten[Position[vars, #] & /@ svars, 1]]

I'd like to improve code readability, perhaps by defining following custom notation for restrict[vars,svars,vals]


(source: yaroslavvb.com)

My questions are

  1. What is a good way to implement this?
  2. Is this a good idea altogether?
Community
  • 1
  • 1
Yaroslav Bulatov
  • 57,332
  • 22
  • 139
  • 197

2 Answers2

4

Good notations can be very useful - but I'm not sure that this particular one is needed...

That said, the Notation package makes this pretty easy. As there are many hidden boxes when you use the Notation palette, I'll use a screenshot: alt text

You can see the underlying NotationMake* downvalues construct by using the Action -> PrintNotationRules option. In[4] in the screenshot generates

NotationMakeExpression[
  SubscriptBox[vals_, RowBox[{vars_, "|", svars_}]], StandardForm] := 
 MakeExpression[
  RowBox[{"restrict", "[", RowBox[{vars, ",", svars, ",", vals}], 
    "]"}], StandardForm]

NotationMakeBoxes[Subscript[vals_, vars_ | svars_], StandardForm] := 
 SubscriptBox[MakeBoxes[vals, StandardForm], 
  RowBox[{Parenthesize[vars, StandardForm, Alternatives], "|", 
    Parenthesize[svars, StandardForm, Alternatives]}]]
Simon
  • 14,631
  • 4
  • 41
  • 101
  • Related question, how do I get to Notation Palette? I found a link to it in one of the Tutorials, but it's not in my Palette's menu – Yaroslav Bulatov Nov 17 '10 at 01:19
  • Provided `Notation`AutoLoadNotationPalette == True` it should open automatically when you `Need["Notation'"]`. If it doesn't then you can open it from `ToFileName[{$InstallationDirectory, "AddOns", "Packages", "Notation", "LocalPalettes", "English"}, ""]` and/or install it from the Palette menu. – Simon Nov 17 '10 at 02:56
3

With regard to 2: I would pass the rule list Thread[vars -> vals] instead of keeping track of names and values separately.
One of my favorite Mathematica idioms is to use rule lists together with WithRules as defined below: This construct evaluates an expression in a With block where all the replacement symbols have been (recursively defined). This allow you to do stuff like

WithRules[{a -> 1, b -> 2 a + 1}, b]

and gets you quite far towards named arguments.

SetAttributes[WithRules, HoldRest]
WithRules[rules_, expr_] := Module[{notSet}, Quiet[
     With[{args = Reverse[rules /. Rule[a_, b_] -> notSet[a, b]]},
       Fold[With[{#2}, #1] &, expr, args]] /. notSet -> Set, 
   With::lvw]]

Edit: The WithRules construct is based on these two usenet threads (thanks to Simon for digging them up):

Janus
  • 5,421
  • 2
  • 26
  • 37
  • It's similar usage to http://stackoverflow.com/questions/4152194/automatically-generating-sums-in-mathematica/4152797#4152797 . IE, I sum f1(x1,x2)*f2(x2,x3) over x1,x2,x3 where fi's arguments are stored in args[fi] – Yaroslav Bulatov Nov 16 '10 at 04:10
  • 1
    OK, so this probably isn't so helpful then. Still, it is my favorite trick, so any excuse will do for posting it :) – Janus Nov 16 '10 at 04:36
  • It is a nice trick. I remember a similar method discussed in [this mathgroup post](https://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/6fa6b0ad9d5d111c). – Simon Nov 16 '10 at 05:51
  • Also [this one](http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/3a5ae92bda1c7511) (which is the actual discussion that I remember!) – Simon Nov 16 '10 at 06:00
  • @Simon: Yes, exactly! Thanks for finding them (I gave it a quick try with no luck). Have added links to my answer for future reference. – Janus Nov 16 '10 at 11:52