# Replacement rules which for elements of a vector which meet conditions

I'm trying to create a function which will replace elements of a list with their values modulo 1, i.e. Mod[x,1], but only if Abs[x]>1. So, for example, the function would yield:

f[{-1.5, -1, 0, 1}] = {.5, -1, 0, 1}


I'm trying to do this in an elegant way. For example, I have a function for a related purpose:

C1[v_] := v /. _?Negative -> 0;


This replaces negative elements of a list with 0, and it's very clean.

I'd like to do something similar. My efforts so far have included breaking it into two functions:

CLim[x_] := Mod[x, 1] /; Abs[x] > 1;

C2[v_] := CQubitLim /@ v;


But then, when I apply C2 to a list, it only seems to apply on some elements, for example

C2[{1, 0, 1.5}] = {Clim[1], CLim[0], 0.5}


My other idea was to use a conditional rule

v :> Mod[v, 1] /; Abs[v] > 1


But this doesn't seem to evaluate when I put a vector through it.

Any ideas much appreciated.

• Does Function[x, If[Abs[x] > 1, Mod[x, 1], x]] /@ {-1.5, -1, 0, 1} suit your needs? – J. M.'s ennui May 27 '20 at 16:29
• @J.M. very elegant, compact solution. – Dan Goldwater May 28 '20 at 9:40

Specify the definition of C2 for cases when Abs[x]<=1:

ClearAll[CLim, C2];
CLim[x_] := Mod[x, 1] /; Abs[x] > 1;
CLim[x_] := x;
C2[v_] := CLim /@ v

C2[{1, 0, -.5, 1.5}]

 {1, 0, -0.5, 0.5}

• I had no idea you could define functions twice like this, with different patterns. This is extremely useful! – Dan Goldwater May 28 '20 at 9:29

One way (perhaps not very elegant) is to use SubsetMap to map the modifying function only onto positions where the absolute value is greater than 1:

lst//SubsetMap[Mod[Abs[#],1]&, #, Pick[Range@Length@#,Sign[Abs[#]-1],1]]&


{0.5, -1, 0, 1}