2
$\begingroup$

I got to a problem where as I just can't find the proper Mathematica command.

I'm given a list, for example:

$\{1,x1,-x1,x2,x5,x3,-x2,-x4\}$

I need this to become

$\{1,x1,x2,x3,x4,x5\}$

The example is just a small possibility with all $x_i$ present. There's only 1 variable at all times. $X =Array[x,6]$

A second example to be more clear. I'll make it a little bit more terrifying: $\{1,x_1,-x_1,x_2,x_5,x_3,-4x_2,-x_4,-1,x_1x_2,-x_3x_5,x_6^2\}$

needs to become

$\{1,x_1,x_2,x_3,x_4,x_1x_2,x_3x_5,x_6^2\}$

$\endgroup$
  • $\begingroup$ DeleteDuplicates would probably be the place to start. You will likely have to use the second argument to the function since you want to count -x1 and x1 as duplicates. $\endgroup$ – KAI Aug 5 '13 at 23:37
  • $\begingroup$ It would be more clear if the examples were written as Mathematica code. Does $x_1$ mean x1, x[1] or Subscript[x,1] ? $\endgroup$ – Simon Woods Aug 6 '13 at 7:59
5
$\begingroup$

Going by the input and output as shown in the question I believe you want Union. For example:

list = {1, x1, -x1, x2, x5, x3, -x2, -x4};

Union[list /. -x_ :> x]
{1, x1, x2, x3, x4, x5}

You did say "There's only 1 variable at all times." Understand that in Mathematica x1 and x2 are separate Symbols. Possibly you want:

list = {1, x 1, -x 1, x 2, x 5, x 3, -x 2, -x 4};

Union[list /. x_*n_?Negative :> -n x]
{1, x, 2 x, 3 x, 4 x, 5 x}

Or:

Union[ Abs[list] /. Abs[n_] :> n ]
{1, x, 2 x, 3 x, 4 x, 5 x}

This is the input form for your second example as I interpret it:

list2 = {1, x[1], -x[1], x[2], x[5], x[3], -4 x[2], -x[4], -1, x[1] x[2], -x[3] x[5], x[6]^2};

If this is incorrect please let me know.

Applying the above method:

Union[Abs[list2] /. Abs[n_] :> n]
{1, x[1], x[2], 4 x[2], x[1] x[2], x[3], x[4], x[5], x[3] x[5], x[6]^2}

We have both x[2] and 4 x[2] which is not shown in your output. The reason for that is not clear to me. Should all coefficients be stripped? Perhaps:

Union[list2 /. {-1 -> 1, _?NumericQ*x[n_] :> x[n]}] ~SortBy~ Length
{1, x[1], x[2], x[3], x[4], x[5], x[1] x[2], x[3] x[5], x[6]^2}

This still has x[5] which your target does not. I don't know why that would be eliminated by not x[3] so I am assuming it is a mistake.

$\endgroup$
  • $\begingroup$ Nice is quite looking like, it didn't mention that it could also become -1 , is it easy to change that to 1? $\endgroup$ – Jban Aug 6 '13 at 0:35
  • $\begingroup$ @Jban Do you mean you may have {1, . . ., -1, . . .} and you want to keep only 1? $\endgroup$ – Mr.Wizard Aug 6 '13 at 0:38
  • $\begingroup$ Its more like x= {x1,x2,x3,x4,x5,x6...xn} That's my only variable, next to them there are all constants positive and negative of which I need all abs's but, abs fails at variables. If you know what I mean... $\endgroup$ – Jban Aug 6 '13 at 0:39
  • $\begingroup$ @Jban Did you see the update to my answer? If that doesn't apply, please give me a specific example and I'll try to address it. $\endgroup$ – Mr.Wizard Aug 6 '13 at 0:41
  • $\begingroup$ I updated my question to become more clear. $\endgroup$ – Jban Aug 6 '13 at 0:48
3
$\begingroup$
array = {1, y1, -y1, y2, y5, y3, -y2, -y4}    
DeleteCases[array, Times[-1, _]]
{1, y1, y2, y5, y3}

If it were possible to have two of any "positive" element in the array like:

array = {1, y1, -y1, y2, y5, y3, -y2, -y4, y5} 

You could remove them by using DeleteDuplicates[]:

DeleteDuplicates[DeleteCases[array, Times[-1, _]]]
{1, y1, y2, y5, y3}
$\endgroup$
  • $\begingroup$ It's almost that what I need, because the $-x_4$ is also deleted, when i still needed it. Thnx allready $\endgroup$ – Jban Aug 5 '13 at 23:51
3
$\begingroup$

You could use a replacement rule to change all the negatives to positives, followed by DeleteDuplicates[].

array = {1, x1, -x1, x2, x5, x3, -x2, -x4}
DeleteDuplicates[array /. Times[-1, x_] -> x]

{1, x1, x2, x5, x3, x4}

$\endgroup$
2
$\begingroup$

Here is an approach that may already be implicit in one or more of the other answers, but I think it should be made explicit.

data1 = {1, x1, -x1, x2, x5, x3, -x2, -x4};
data2 = {1, x1, -x1, x2, x5, x3, -4 x2, -x4, -1, x1 x2, -x3 x5, x6^2};

f[data_List] := 
  DeleteDuplicates[data /. {Times[_Integer, x_] -> x, x_Integer?Negative -> -x}]

f[data1]
f[data2]

{1, x1, x2, x3, x4, x5}
{1, x1, x2, x1 x2, x3, x4, x5, x3 x5, x6^2}

Edit

As Mike Honeychurch suggests, if it's not clear how this works, you should take a look at the full form of data2.

data2 // FullForm
List[
   1, x1, Times[-1, x1], x2, x5, x3, Times[-4, x2], Times[-1, x4], -1, 
   Times[x1, x2], Times[-1, x3, x5], Power[x6, 2]
 ]

This shows that the primary problem is to deal with expressions of the form Times[_Integer, x_]. These are handled by the first rule in the ReplaceAll expression

data /. {Times[_Integer, x_] -> x, x_Integer?Negative -> -x}

There is a secondary problem of dealing with negative integer constants. These are handled by the second rule.

$\endgroup$
  • $\begingroup$ Might be worth adding a copy of FullForm[data2] to help him visualize what is occurring ...for own learning benefit etc. $\endgroup$ – Mike Honeychurch Aug 6 '13 at 10:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.