18
$\begingroup$

This is probably a very simple question, but I couldn't find a duplicate.

As everybody knows, {x, y} + v gives {x + v, y + v}. But if I intend v to represent a vector, for example if I am going to substitute v -> {vx, vy} in the future, then the result {x + v, y + v} is meaningless.

How I can indicate to Mathematica that v is not a scalar and functions like Plus should not treat it as one? I tried setting $Assumptions = v ∈ Vectors[2] but that didn't help.

$\endgroup$
  • 1
    $\begingroup$ I suppose you don't want to Inactivate Plus because there are other computations you want to do? $\endgroup$ – march Dec 24 '15 at 3:51
  • $\begingroup$ Thanks for all the answers, everyone! I guess I should have been more forthcoming about my ultimate goal, namely getting a correct PiecewiseExpand[f[t, 0, 2]] for my Koch snowflake parametrization, because I couldn't figure out make the answers here work for it. But seeing all the different approaches inspired a solution of my own that did work out (though still not as elegant as I would like). $\endgroup$ – user484 Dec 25 '15 at 2:51
7
$\begingroup$

You can use Inactivate

pl = Inactivate[{x, y} + v, Plus]

enter image description here

As an indication to not being "active" the plus sign is dimmed

You can still use a (partially) inactivated expression

ti = pl * 8

enter image description here

and Activate it whenever you want

Activate[ti]

enter image description here

| improve this answer | |
$\endgroup$
5
$\begingroup$

One workaround would be ClearAttributes[Plus,Listable] (The Plus is threading because of the Listable attribute). If you need the Listable attribute in another part of your code, you would need to run SetAttributes[Plus,Listable] to put the attribute back in.

ClearAttributes[Plus,Listable];
{x, y} + v

(* v + {x, y} *)

Or, you could simply use Defer (a bit tricky to use):

Defer[{x, y} + v]

(* {x, y} + v *)

Alternatively, you could use Hold (or HoldForm) and ReleaseHold:

ReleaseHold[Hold[{x, y} + v] /. v -> {vx, vy}]

(* {vx + x, vy + y} *)
| improve this answer | |
$\endgroup$
  • $\begingroup$ Clearing Listable makes {a,b}+{c,d} not evaluate as expected. $\endgroup$ – Ruslan Sep 1 '16 at 20:59
5
$\begingroup$

I like to wrap lists in some suitable function to block this evaluation. MatrixForm is good because it looks pretty, but an undefined function would also work.

a = MatrixForm[{x, y}] + MatrixForm[v]

Then, once you have concrete definitions for your arrays, take away the MatrixForm:

b = a /. v -> {1, 2}
b /. MatrixForm -> Identity
(* {1 + x, 2 + y} *)
| improve this answer | |
$\endgroup$
4
$\begingroup$

You may use Indexed to represent v as its components in the calculation.

{x, y} + (Indexed[v, #] & /@ Range[2])
(* {x + Indexed[v, {1}], y + Indexed[v, {2}]} *)

Later when v is assigned the Indexed components will become Part values of v.

v = {1, 2};
{x, y} + (Indexed[v, #] & /@ Range[2])
(* {1 + x, 2 + y} *)

As a function

f[t_] := {x, y} + (Indexed[t, #] & /@ Range[2])

Hope this helps.

| improve this answer | |
$\endgroup$
3
$\begingroup$

If there's a specific addition operation one wants to block, one can just apply a custom function instead, for example

{x, y} ~plus~ v
(* plus[{x, y}, v] *)

and replace it with Plus when one is ready:

{x, y} ~plus~ v /. v -> {vx, vy} /. plus -> Plus
(* {vx + x, vy + y} *)
| improve this answer | |
$\endgroup$
2
$\begingroup$

Another option, which doesn't require activation/replacement-by-identity/manual-indexing/etc. is to create a custom Plus function, which only evaluates for lists:

vectorPlus[a_?ListQ,b_?ListQ]=a+b;

With it you have:

vectorPlus[x, {q,r,s}]
vectorPlus[{q,r,s}, y]
vectorPlus[{q,r,s}, y] /. y->{a,b,c}
vectorPlus[{q,r,s}, {x,y,z}]

vectorPlus[x, {q, r, s}]

vectorPlus[{q, r, s}, y]

{a + q, b + r, c + s}

{q + x, r + y, s + z}

| improve this answer | |
$\endgroup$

Your Answer

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