I'm doing a computation which effectively has the same issue as this code:
Range@1000000 /. (Alternatives@@RandomSample[Range@1000000,500000]) -> 0
i.e. replacing each element of an arbitrary but large subset with a constant. So, how can code like list /. Alternatives@@subset->0
be made faster when subset
is very large (close to half the size of list
, so no benefit from inverting) and doesn't contain any exploitable patterns?
Perhaps the motivating problem is easier to solve: select those triangles in a mesh which cross an InfinitePlane, say InfinitePlane@{{0,0,0},{1,0,0},{0,0,1}}. So, given a MeshRegion m
,
fwd=First/@Position[MeshCoordinates@m,{_,_?Positive,_}]
back=First/@Position[MeshCoordinates@m,{_,_?NonPositive,_}]
Position[
MeshCells[m,{2}]/.{Alternatives@@fwd->0,Alternatives@@back->1}
Polygon@{OrderlessPatternSequence[{1,0,_}]}]
I'm sure this could be made better, but I'm curious about the question it prompts about large Alternative
s statements.
A way to do it better: don't 'cache' the results of Positive
, and simply delete those polygons that are entirely on one side or the other:
Delete[MeshCells[m,{2}],
Position[MeshPrimitives[m,{2}],
Polygon[{{_,_?Positive,_},
{_,_?Positive,_},
{_,_?Positive, _}} |
{{_,_?NonPositive,_},
{_,_?NonPositive,_},
{_,_?NonPositive,_}}
]
]
]
I can't figure out how to effectively use Dispatch
or some clever numerical/floating point tricks to speed it up.