5
$\begingroup$

I have a list of 3 pairs of integers, for each pair i I want to replace the one having the smallest absolute value with xi and the other one with its sign. Like this:

In: {{-5, 1}, {7, -3}, {4, 4}}
Out: {{-1, x2}, {1, x3}, {x4, 1}} (*for the last one {1, x4} would be fine as well*)

My attempt is this, I fear it's a bit too convoluted:

list = {{-5,1},{7,-3},{4,4}}
list = MapThread[#1 /. #2 -> #3 &, {list, If[Total[#] > 0, Min[#], Max[#]] & /@ list, {x1, x2, x3}}];
list = Map[If[NumericQ[#], Sign[#], #] &, list, {2}];

I'm using this in a fractal related problem, so what's the most optimized way?

$\endgroup$
3
  • 2
    $\begingroup$ Man, this just SCREAMS XY-problem :-) Why do you need to do this and what would you like to accomplish with it ultimately? $\endgroup$
    – MarcoB
    Commented Dec 9, 2020 at 23:42
  • $\begingroup$ :D @MarcoB Yes, you're right, take a glimpse at this I'm now trying to take that idea further and find the tangent circumference in every area that shows up, a fractal. NMinimize is the core function that actually finds centers and radii. Basically the 3 pairs of integers in this question are slope vector, they are parameterized with x1, x2, x3 normalized and feeded to NMinimize. They tell in which half plane to look for the next circle $\endgroup$ Commented Dec 10, 2020 at 1:47
  • $\begingroup$ I've just learned that the circle tangent to 3 mutually tangent circles (being a solved problem) can be calculated... So technically I won't use this procedure in that case. But I'll need anyway for the area between 2 circle and one curve. $\endgroup$ Commented Dec 10, 2020 at 1:56

2 Answers 2

5
$\begingroup$
ClearAll[f]
f = MapIndexed[If[LessEqual @@ Abs @ #,
  {Symbol["x" <> ToString[#2[[1]]]],  Sign @ Last @ #}, 
  {Sign @ First @ #,  Symbol["x" <> ToString[#2[[1]]]]}] &];

list = {{-5, 1}, {7, -3}, {4, 4}}; 

f @ list
{{-1, x1}, {1, x2}, {x3, 1}}

Also

symbolpositions = MapIndexed[Flatten[{#2, #}] &][2 - Boole[LessEqual @@@ Abs[list]]];

symbols = Symbol["x" <> ToString[#]] & /@ Range[Length@list];

ReplacePart[Sign@list, Thread[symbolpositions -> symbols]]
 {{-1, x1}, {1, x2}, {x3, 1}}
$\endgroup$
3
$\begingroup$

MapIndexed should be the suitable function working at the overall level. A version slightly different from that of @kglr 's, with OrderingBy, ToExpression, and StringTemplate

symbol = ToExpression[StringTemplate["x``"] @@ #] &;
func = If[Greater @@ OrderingBy[#, Abs],
    {Sign[#[[1]]], symbol[#2]}, 
    {symbol[#2], Sign[#[[2]]]}
] &;
list = {{-5, 1}, {7, -3}, {4, 4}};
MapIndexed[func][list]
{{-1, x1}, {1, x2}, {x3, 1}}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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