1

EDIT: Added that I want to extract not only the variables from a specific set, but also functions involving variables from a specific set.

Given the set

S = [s1, s2, s3]

and some vector of values

x = {1, 2, 4, s1, y, f1[s1], f2[s2]}

I want to pick out all values in x that belong to the set S, and also all functions involving arguments with from the set S. Maybe some approach like

Smash[x_] := Cases[{x}, _, {0, Infinity}] (*Eq. Smash[f1[s1]] = {f1[s1],s1})
Select[x, IntersectingQ[Smash[#], S] ]

But it really doesn't work. I guess it's an issue regarding the syntax mainly, I don't really know what do with #. How can I solve this? Any answers explaining the syntax issue or giving alternative solutions will be greatly appreciated.

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
Martin
  • 21
  • 2
  • 2
    (i) you should change square brackets in assignment of S (ii) avoid capital letters to avoid conflicts with MMA built-ins (iii)why not use Intersection[S,x].(iv) to make you own code work just put an & at the end of your criterion – ubpdqn Feb 27 '16 at 11:57
  • Welcome to Mathematica.StackExchange Martin. I attempted to address your needs in an answer below. Nevertheless this question will probably be closed as "easily found in the documentation." I know the documentation can be opaque at times. Consider possibly also making use of these resources: http://www.mathprogramming-intro.org/ and (18393) as well as the links in the Introduction section of (18). – Mr.Wizard Feb 27 '16 at 12:00
  • ubpdqn: Thy! Just tried

    Select[x, IntersectingQ[Smash[#], S] &] but it gives me

    Tag Slot in #1 is Protected.

    – Martin Feb 27 '16 at 12:57
  • There are things to do after your question is answered. It's a good idea to stay vigilant for some time, better approaches may come later improving over previous replies. Experienced users may point alternatives, caveats or limitations. New users should test answers before voting and wait 24 hours before accepting the best one. Participation is essential for the site, please come back to do your part tomorrow – rhermans May 15 '17 at 14:22

2 Answers2

7

What I think you want:

S = {s1, s2, s3};

x = {1, 2, 4, s1, y};

Intersection[x, S]

Outputs: {s1}

As for # see http://reference.wolfram.com/language/tutorial/PureFunctions.html


For your edited question:

set = {s1, s2, s3};
x = {1, 2, 4, s1, y, f1[s1], f2[s2]}

p = Alternatives @@ set;

Cases[x, p | _[p]]
{s1, f1[s1], f2[s2]}

Reference Alternatives.


Addressing your most recent comment I think you want:

set = {s1, s2, s3};
x = {1, 2, f1[s1 + s2] , f2[f1[s1] + s3], 4, f3[s1 + q], s1, y, f1[s1], f2[s2]}

p = Alternatives @@ set;

Select[x, Not@*FreeQ[p]]
{f1[s1 + s2], f2[s3 + f1[s1]], f3[q + s1], s1, f1[s1], f2[s2]}

Reference FreeQ and Composition.

If however you wish to exclude f3[q + s1] because of q you will need to look at the leaves of the expression, but not heads:

Select[x, FreeQ[#, Except[p], {-1}, Heads -> False] &]
{f1[s1 + s2], f2[s3 + f1[s1]], s1, f1[s1], f2[s2]}

Reference: Levels: how do they work?

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • did you think my comment was terse or discourteous? I did not mean it that way. – ubpdqn Feb 27 '16 at 12:24
  • @ubpdqn Are you asking me that because I also posted a comment? I was writing it before yours appeared. I see no problem with your comment. In fact you mentioned that user symbols starting with Capital Letters is a bad idea, which is something I forgot. – Mr.Wizard Feb 27 '16 at 12:52
  • No it was a great answer! However, I just realised that the question is a bit more extensive than I first thought. I updated the original post. – Martin Feb 27 '16 at 12:53
  • @Mr.Wizard I think I felt guilty for not sating welcome or putting a format welcome message. I just thought it could be resolved quickly. – ubpdqn Feb 27 '16 at 12:54
  • Neat, really neat! Tried to upvote your answer but I don't have reputation enough to do it. Thank you! – Martin Feb 27 '16 at 13:08
  • Next challenge is that I want to extract a function containing any expression related to the set, for instance f1[s1+s2] or f2[f1[s1]+s3].

    Really got stuck here. Guess some recursion could solve it. Hmm.

    – Martin Feb 27 '16 at 13:36
7

It is not completely clear to me what form the output is intended to take. Recommend that you always give examples of both inputs and corresponding outputs.

S = {s1, s2, s3};

x = {1, 2, 4, s1, y, f1[s1], f2[s2], f1[s1 + s2], f2[f1[s1] + s3]};

DeleteCases[x, _?(FreeQ[#, Alternatives @@ S] &)]

(*  {s1, f1[s1], f2[s2], f1[s1 + s2], f2[s3 + f1[s1]]}  *)
Bob Hanlon
  • 157,611
  • 7
  • 77
  • 198