2
$\begingroup$

I want to create a piecewise function that depends on the length of the list. Let's say I have a list, and a corresponding piecewise function:

list1={a,b,c}
pFun=Piecewise[{{{1, x}, x <= list1[[1]]}, {{2, x}, list1[[2]] < x <= list1[[3]]}}, {3, x}]

now say if I change the length of the list to 4,

list1={a,b,c,d}

Is there any possible way to automate the Piecewise function, such that list1[[3]] < x <= list1[[4]] is added based on the length of the list list1? The length of list1 keeps changing and I can't edit pFun everytime. Any help is appreciated.

$\endgroup$
2
  • 1
    $\begingroup$ Just to clarify. (1) The piecewise function never depends on the last value of list1 in any way. (2) The gap between list1[[1]] and list1[[2]] isn't explicitly covered by the conditions. Correct? $\endgroup$
    – lericr
    May 26, 2022 at 1:54
  • $\begingroup$ that's my bad, the list should be {a,b,c} and the last conditional is True or x>=c, either is fine. Thanks for looking into it. $\endgroup$
    – Rupesh
    May 26, 2022 at 3:35

2 Answers 2

4
$\begingroup$

This doesn't replicate your example, but I'm not sure how to interpret your example. I would probably do something like the following (modify to suit).

(* A function to create the condition parts *)
ToConditions[list_, sym_] := Append[(#1 < sym <= #2) & @@@ Partition[list, 2, 1], True];
ToConditions[Range@4, x]
(* gives {1<x<=2,2<x<=3,3<x<=4,True} *)

(* A function to create the value parts *)
ToValues[list_, sym_] := {#, sym} & /@ list;
ToValues[Range@4, x]
(* gives {{1,x},{2,x},{3,x},{4,x}} *)

Put it together:

Piecewise@Thread[{ToValues[Range@4, x], ToConditions[Range@4, x]}]

gives: enter image description here

$\endgroup$
2
  • $\begingroup$ Thank you for the answer but the first conditional would be x<=1. $\endgroup$
    – Rupesh
    May 26, 2022 at 3:26
  • $\begingroup$ I think I got the answer by tweaking your code a little bit. ToConditions[list_, sym_] := Flatten[{sym >= list[[1]], (#1 < sym <= #2) & @@@ Partition[list[[2 ;;]], 2, 1], True}];. This will do it. Thank you so much $\endgroup$
    – Rupesh
    May 26, 2022 at 4:13
0
$\begingroup$

You can use MapIndexed.

pw[lst_List, sym_Symbol] :=
 Piecewise[
  MapIndexed[
   {v, i} |-> {{First@i, sym}, sym <= v}
   , lst
   ]
  , Null
  ]

Then

pw[{a, b, c}, x]

enter image description here

and

pw[{a, b, c, h}, y]

enter image description here

Hope this helps.

$\endgroup$
2
  • 1
    $\begingroup$ Thanks Edmund, but the conditionals are y<=a, a<y<=b,b<y<=c and so on... $\endgroup$
    – Rupesh
    May 26, 2022 at 3:28
  • $\begingroup$ @Rupesh For your constraints you do not need to specify the lower bound as piecewise evaluates each condition in order and stops when a. condition is met. The constraints I have implemented are mathematically equivalent. $\endgroup$
    – Edmund
    May 26, 2022 at 15:55

Your Answer

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

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