2
$\begingroup$

Consider two arrays (ar1, ar2) as

ar1 = RandomInteger[5,4];
ar2 = RandomInteger[5,3];

Now I have a set of equations as follows:

ar3[[1]] = 2*(ar1[[0]]*ar2[[1]]+ar1[[1]]*ar2[[2]]+ar1[[2]]*ar2[[3]]);
ar3[[2]] = 3*(ar1[[1]]*ar2[[1]]+ar1[[2]]*ar2[[2]]+ar1[[3]]*ar2[[3]]);
ar3[[3]] = 3*(ar1[[2]]*ar2[[1]]+ar1[[3]]*ar2[[2]]+ar1[[4]]*ar2[[3]]);
ar3[[4]] = 2*(ar1[[3]]*ar2[[1]]+ar1[[4]]*ar2[[2]]+ar1[[5]]*ar2[[3]]);

Clearly, ar1[[0]] is the List which is not desired and for ar1[[5]] the index is out of bounds and the numbers at the beginning of the rhs indicate the numbers of valid terms summed up. In this smaller set, it is possible to manually discard the terms (e.g. ar1[[0]]*ar2[[1]]) corresponding to such elements. How can I do it programmatically for a much larger set?

Edit 1: Following the answers, I think one constraint is overlooked and that is the first number on the rhs. This indicates the number of valid expressions to be summed up. These numbers are input manually even in the answers. However, I want the number to be computed programmatically.

$\endgroup$
  • $\begingroup$ ListConvolve[ar2, ar1, {2, -2}, 0] will produce the outputs you want without the prefactors. You can add the prefactors by hand afterward since it is a vector whose length is the same as ar1, with values that are the length of ar2, except that the endpoints are decremented. $\endgroup$ – Carl Woll Feb 23 '18 at 16:31
1
$\begingroup$

Clearly, your ar3 needs to be defined too and I strongly advise that you tackle this problem earlier in your chain when you created those invalid Part expressions. Anyway, you can hold your expression so that it does not evaluate and replace all invalid array accesses like this:

ar1 = RandomInteger[5, 4];
ar2 = RandomInteger[5, 3];
ar3 = ConstantArray[0, 4];

Hold[
  ar3[[1]] = 2*(ar1[[0]]*ar2[[1]] + ar1[[1]]*ar2[[2]] + ar1[[2]]*ar2[[3]]); 
  ar3[[2]] = 3*(ar1[[1]]*ar2[[1]] + ar1[[2]]*ar2[[2]] + ar1[[3]]*ar2[[3]]); 
  ar3[[3]] = 3*(ar1[[2]]*ar2[[1]] + ar1[[3]]*ar2[[2]] + ar1[[4]]*ar2[[3]]); 
  ar3[[4]] = 2*(ar1[[3]]*ar2[[1]] + ar1[[4]]*ar2[[2]] + ar1[[5]]*ar2[[3]]);
  ] /. HoldPattern[l_[[i_]]] :> 0 /; i < 1 || i > Length[l]

If this is OK, you can evaluate it by using ReleaseHold[%].

$\endgroup$
1
$\begingroup$

You can try this “hack”:

NullifyMissing[expr_] := 
    Hold[expr] /. HoldPattern[ar_[[n_]]] :> 0 /; n <= 0 || n > Length[ar] // ReleaseHold
SetAttributes[NullifyMissing, HoldFirst]

It replaces all the missing elements with 0:

ar3 = Table[0, {4}];
ar3[[1]] = 2*(ar1[[0]]*ar2[[1]] + ar1[[1]]*ar2[[2]] + ar1[[2]]*ar2[[3]]) // NullifyMissing;
ar3[[2]] = 3*(ar1[[1]]*ar2[[1]] + ar1[[2]]*ar2[[2]] + ar1[[3]]*ar2[[3]]) // NullifyMissing;
ar3[[3]] = 3*(ar1[[2]]*ar2[[1]] + ar1[[3]]*ar2[[2]] + ar1[[4]]*ar2[[3]]) // NullifyMissing;
ar3[[4]] = 2*(ar1[[3]]*ar2[[1]] + ar1[[4]]*ar2[[2]] + ar1[[5]]*ar2[[3]]) // NullifyMissing;

But I would suggest that you construct your table in more explicit way:

In[1]:= ar1 = {a1, a2, a3, a4};
        ar2 = {b1, b2, b3, b4};
        cf  = {2, 3, 3, 2};

In[4]:= Ar1[index_Integer] := Piecewise[{ar1[[index]], 0 < index <= Length[ar1]}];
        Ar1[index_Span] := Table[Ar1[i], {i, Range @@ index}];

In[6]:= ar3 = Table[cf[[i]] Ar1[i-1 ;; i+1].ar2[[1 ;; 3]], {i, 4}]

Out[6]= {2 (a1 b2 + a2 b3), 3 (a1 b1 + a2 b2 + a3 b3),
         3 (a2 b1 + a3 b2 + a4 b3), 2 (a3 b1 + a4 b2)}
$\endgroup$

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.