Skip to main content
replaced http://mathematica.stackexchange.com/ with https://mathematica.stackexchange.com/
Source Link

Since you apparently want something Mathematica-like, as opposed to a procedural loop, here's a take on it. Note, as belisariusbelisarius commented, we really ought to check whether the exact root has accidentally been found. That adds some case-checking. I'll discuss pattern-checking the arguments later. You may note I defined a realQ to replace NumericQ. This may be over-fastidious, but complex numbers will not work.

Using a PatternTest versus a Condition for pattern matchingUsing a PatternTest versus a Condition for pattern matching
_?NumericQ equivalent for lists_?NumericQ equivalent for lists
How to program a F::argx message?How to program a F::argx message?
*More elegant wayMore elegant way
*Quick way to use conditioned patterns when defining multi-argument function?Quick way to use conditioned patterns when defining multi-argument function?
*How to avoid repeated pattern tests in function definitionsHow to avoid repeated pattern tests in function definitions

For users of V9 and earlier, you can use these replacements for DeleteDuplicatesBy and BooleanQ. The code for DeleteDuplicatesBy below is basically Mr.Wizard's myDeDupeBy in his answer to his question, DeleteDuplicatesBy is not performing as I'd hoped. Am I missing something?DeleteDuplicatesBy is not performing as I'd hoped. Am I missing something? Perhaps everyone should be using it.

Since you apparently want something Mathematica-like, as opposed to a procedural loop, here's a take on it. Note, as belisarius commented, we really ought to check whether the exact root has accidentally been found. That adds some case-checking. I'll discuss pattern-checking the arguments later. You may note I defined a realQ to replace NumericQ. This may be over-fastidious, but complex numbers will not work.

Using a PatternTest versus a Condition for pattern matching
_?NumericQ equivalent for lists
How to program a F::argx message?
*More elegant way
*Quick way to use conditioned patterns when defining multi-argument function?
*How to avoid repeated pattern tests in function definitions

For users of V9 and earlier, you can use these replacements for DeleteDuplicatesBy and BooleanQ. The code for DeleteDuplicatesBy below is basically Mr.Wizard's myDeDupeBy in his answer to his question, DeleteDuplicatesBy is not performing as I'd hoped. Am I missing something? Perhaps everyone should be using it.

Since you apparently want something Mathematica-like, as opposed to a procedural loop, here's a take on it. Note, as belisarius commented, we really ought to check whether the exact root has accidentally been found. That adds some case-checking. I'll discuss pattern-checking the arguments later. You may note I defined a realQ to replace NumericQ. This may be over-fastidious, but complex numbers will not work.

Using a PatternTest versus a Condition for pattern matching
_?NumericQ equivalent for lists
How to program a F::argx message?
*More elegant way
*Quick way to use conditioned patterns when defining multi-argument function?
*How to avoid repeated pattern tests in function definitions

For users of V9 and earlier, you can use these replacements for DeleteDuplicatesBy and BooleanQ. The code for DeleteDuplicatesBy below is basically Mr.Wizard's myDeDupeBy in his answer to his question, DeleteDuplicatesBy is not performing as I'd hoped. Am I missing something? Perhaps everyone should be using it.

bug fix
Source Link
Mr.Wizard
  • 273.1k
  • 34
  • 595
  • 1.4k
DeleteDuplicatesBy[x_, f_] := GatherBy[x, Last][[Allf][[All, 1]]

BooleanQ = MatchQ[#, True | False] &
DeleteDuplicatesBy[x_, f_] := GatherBy[x, Last][[All, 1]]

BooleanQ = MatchQ[#, True | False] &
DeleteDuplicatesBy[x_, f_] := GatherBy[x, f][[All, 1]]

BooleanQ = MatchQ[#, True | False] &
added 34 characters in body
Source Link
Michael E2
  • 244.7k
  • 18
  • 351
  • 774
splitInterval[func_, v : {{a_, sgna_}, {b_, sgnb_}}] := 
 With[{sgn = Sign[func[(a + b)/2]]},
  If[sgn == 0,
   {{(a + b)/2, sgn}, {(a + b)/2, sgn}},
   DeleteDuplicatesBy[Join[{{(a + b)/2, sgn}}, v], Last]]  (* see Pre V10 note at bottom *)
  ]

ClearAll[biSection2];
realQ = Quiet@Check[BooleanQ[# < 0], False] &;
biSection2[func_, {a0_?realQ, b0_?realQ}, ξ_?realQ] := 
 With[{sgna = Sign[func[a0]], sgnb = Sign[func[b0]]},
  Which[
    sgna == 0
    , {a0, a0},
    sgnb == 0
    , {b0, b0},
    True
    , Sort[
     First /@ 
      NestWhile[splitInterval[func, #] &, {{a0, sgna}, {b0, sgnb}}, 
       Abs@(Subtract @@ #[[All, 1]]) > ξ &]]
    ] /; sgna*sgnb <= 0
  ]
splitInterval[func_, v : {{a_, sgna_}, {b_, sgnb_}}] := 
 With[{sgn = Sign[func[(a + b)/2]]},
  If[sgn == 0,
   {{(a + b)/2, sgn}, {(a + b)/2, sgn}},
   DeleteDuplicatesBy[Join[{{(a + b)/2, sgn}}, v], Last]]
  ]

ClearAll[biSection2];
realQ = Quiet@Check[BooleanQ[# < 0], False] &;
biSection2[func_, {a0_?realQ, b0_?realQ}, ξ_?realQ] := 
 With[{sgna = Sign[func[a0]], sgnb = Sign[func[b0]]},
  Which[
    sgna == 0
    , {a0, a0},
    sgnb == 0
    , {b0, b0},
    True
    , Sort[
     First /@ 
      NestWhile[splitInterval[func, #] &, {{a0, sgna}, {b0, sgnb}}, 
       Abs@(Subtract @@ #[[All, 1]]) > ξ &]]
    ] /; sgna*sgnb <= 0
  ]
splitInterval[func_, v : {{a_, sgna_}, {b_, sgnb_}}] := 
 With[{sgn = Sign[func[(a + b)/2]]},
  If[sgn == 0,
   {{(a + b)/2, sgn}, {(a + b)/2, sgn}},
   DeleteDuplicatesBy[Join[{{(a + b)/2, sgn}}, v], Last]]  (* see Pre V10 note at bottom *)
  ]

ClearAll[biSection2];
realQ = Quiet@Check[BooleanQ[# < 0], False] &;
biSection2[func_, {a0_?realQ, b0_?realQ}, ξ_?realQ] := 
 With[{sgna = Sign[func[a0]], sgnb = Sign[func[b0]]},
  Which[
    sgna == 0
    , {a0, a0},
    sgnb == 0
    , {b0, b0},
    True
    , Sort[
     First /@ 
      NestWhile[splitInterval[func, #] &, {{a0, sgna}, {b0, sgnb}}, 
       Abs@(Subtract @@ #[[All, 1]]) > ξ &]]
    ] /; sgna*sgnb <= 0
  ]
Added V9 solution
Source Link
Michael E2
  • 244.7k
  • 18
  • 351
  • 774
Loading
Improved formatting
Source Link
Michael E2
  • 244.7k
  • 18
  • 351
  • 774
Loading
Completed answer
Source Link
Michael E2
  • 244.7k
  • 18
  • 351
  • 774
Loading
Source Link
Michael E2
  • 244.7k
  • 18
  • 351
  • 774
Loading