2
$\begingroup$

I'm using Array to create function lists, f[1],f[2],f[3],...,f[A] where the values from $1$ through $A$ have unit increment. This seems an efficient way to do so for my use case: dynamically solving a large number of non-linear equations.

Sadly, some of the related non-linear equations are only defined for certain values between $1$ and $A$, and so I wish to omit the values for which the related equations are undefined. Peculiarly enough I seem to be unable to manipulate data sets created using Array. DeleteCases, something I use usually for regular "lists", requires a pattern that Array uses that I'm unaware of, so I cannot check for the right pattern to delete certain values. For example suppose my function is called Myfunction, then using Fold[DeleteCases[#1,#2[[1]],#2[[2]]],Myarray,{Myfunction,ListofIndicesToDelete}] (up to a Transpose, depends on the exact input) that doesn't work at all.

Suppose the following code:

MyLength = 50;

MyNonLinearEquation[j_] := 
 Subscript[x, j] == Sum[Subscript[x, j]*Subscript[x, k], {k, MyLength}]

MyArray = Array[MyNonLinearEquation, MyLength];

Suppose I wish to omit MyNonLinearEquation[10], and MyNonLinearEquation[35], how would I go about that? Note that we would also have to omit dependencies on these variables inside the sum.

$\endgroup$
1
  • $\begingroup$ Is it like you want to run MyNonLinearEquation skipping curtain indices? $\endgroup$
    – SuTron
    Sep 25 '19 at 11:04
2
$\begingroup$
$indicesToExclude = {10, 35};

arr := Array[MyNonLinearEquation, MyLength];

(*
    First method - just don't use them!
    Note you have contiguous sequence.
*)
tL1 = First@RepeatedTiming[(l1 = MyNonLinearEquation /@ DeleteCases[Range[MyLength], Alternatives @@ $indicesToExclude]);];

(*
    Second method - just don't use them!
    Say you don't contiguous sequence.
*)
tL2 = First@RepeatedTiming[(l2 = MyNonLinearEquation /@ Delete[Range[MyLength], List /@ $indicesToExclude]);];

(*
    Third method - delete at positions!
*)
tL3 = First@RepeatedTiming[(l3 = Delete[arr, List /@ $indicesToExclude]);];

(*
    Fourth method - use overload!
    While writing the response noticed @kglr, already mentioned this.
*)
tL4 = First@RepeatedTiming[(l4 = Array[MyNonLinearEquation, MyLength, 1, Delete[{##}, List /@ $indicesToExclude]&]);];

(*
    Fifth method - using table!
    Demonstrating the answer from @kglr in the benchmark.
*)
tL5 = First@RepeatedTiming[(l5 = Table[MyNonLinearEquation[i], {i, Delete[Range[MyLength], List /@ $indicesToExclude]}]);];

Dataset[<|
    "Method 1" -> <|"Time" -> tL1|>,
    "Method 2" -> <|"Time" -> tL2|>,
    "Method 3" -> <|"Time" -> tL3|>,
    "Method 4" -> <|"Time" -> tL4|>,
    "Method 5" -> <|"Time" -> tL5|>
|>]

SameQ @@ {l1, l2, l3, l4, l5} (* \[Rule] True *)

Dataset result

There are many more methods, you might want to tweak, but I hope this gives you the idea.

$\endgroup$
1
  • $\begingroup$ Wonderful! Went with your second method :-) Many thanks $\endgroup$
    – 1010011010
    Sep 25 '19 at 14:27
5
$\begingroup$
  1. You can use the fourth argument of Array to delete unwanted positions:

Array[foo, 10, 1, Delete[{##}, {{3}, {7}}] &]

{foo[1], foo[2], foo[4], foo[5], foo[6], foo[8], foo[9], foo[10]}

  1. Define bar to be equal to Nothing for the arguments you want to skip and to foo for all other arguments:

bar = foo;
bar[3 | 7] = Nothing;
Array[bar, 10]

{foo[1], foo[2], foo[4], foo[5], foo[6], foo[8], foo[9], foo[10]}

  1. Alternatively, use Table and delete the unwanted positions in the iterator list:

Table[foo[i], {i, Delete[Range@10, {{3}, {7}}]}]

{foo[1], foo[2], foo[4], foo[5], foo[6], foo[8], foo[9], foo[10]}

$\endgroup$
1
  • $\begingroup$ Many thanks! I only marked the other answer because the implementation was easier for my specific use case. Did upvote though:) $\endgroup$
    – 1010011010
    Sep 25 '19 at 14:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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