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$ – Rahul 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

$\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} *)
$\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} *)
$\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.

$\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} *)
$\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}

$\endgroup$

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.