Community Tip - Your Friends List is a way to easily have access to the community members that you interact with the most! X
I am trying to evaluate the sum shown below. I get "This array index is invalid for this array" but I don't see it. I would have thought that if the upper value in the sum is less than the lower, MC would give zero. That is not the case. Maybe this is the problem but, if so, I don't see how to solve it. As always, any help would be appreciated.
Solved! Go to Solution.
OK, this was a tricky one which took some time until I realized whats the cause for the difference.
The error occurs because Luc's attempt does not prevent the summation from 1 to 0 from being executed. It only sets the nominators of the summands used in the process to C0. The approach therefore only works because C0 is fortunately set to zero and therefore these sums, which should actually be avoided, only add zeros. That is also why I do not particularly like this approach - it would not work if C has to be initialized with a value different from zero.
So when m runs through the values 1 and 0, the last summand gives us the expression 0/0 for m=0. This is undefined, and therefore it is perfectly fine for Mathcad to issue an error message here.
In Mathcad 14/15, however, there is an option in the worksheet options to set 0/0 to be treated as 0.
"Tools" - "Worksheet Options..." then tab "Calculation"
In the sheet you posted the option 0/0 = 0 was not checked and that's the cause Mathcad treated 0/0 the correct mathematical way and threw an error 😉
ConcLM only works if this option is enabled (and if C0 is always initialized to 0). Of course it still fails for Maxk=1, which is why I included the branch before the loop in my version. This may also solve your problem in the other sheet, but I would rather prefer ConcSB over ConcLM.
According you attempts with ConcWExx in the other sheet: If you initialize C with just one value instead of 2 (like I did using the stack function) you must assure that you create a vector, not a scalar.
So I guess this is what you are trying to achieve
The last line would not be mandatory but I feel its good style to explicitly state a return value.
Find also similar SB and LM versions in the attached sheet. Personally I would settle for SB. SB also does not avoid the unwanted summations to be done, but it explicitly adds plain zeros (not only setting the nominators to zero). So this version (like the WE) also works if the option 0/0=0 is not set.
I was also curious concerning efficiency wrt calc time.
WE and SB can be considered to be equivalent. The effect with LM can probably be explained by the many calls to the external function “lim”
I haven’t got MM15, I’m afraid.
However, if you (and, presumably, your calculation) expect the sum over m to be zero when k = 0, can you just put the summation inside an if function that returns zero when k = 0 otherwise the sum?
Stuart
Now I'm at a Mathcad laptop again ...
Something like below:
Stuart
I am missing your worksheet!
The sum operator is not implemented in Mathcad in a way conforming to mathematical standards. If the upper summation limit is lower than the lower one, the result should be zero ('empty sum') -> https://en.wikipedia.org/wiki/Summation#Formal_definition
But the implementation in Mathcad unfortunately was done by programmers who thought that the summation operator should work like a for-loop.
So when in your program k=0, the sum runs from 1 down to 0 and consists of two summands, the first with m=1 and the second with m=0. With m=1 your calculation tries to access C with index -1, which of course does not exist. with m=0 you would try to access C with index 1 which also does not yet exist, its just about to be created.
You may cope with this problem using an if-statement but in your case I guess its easier to simply predefine C[1 along with C[0 and let k run from 1 to Maxk (or better Maxk-1, see below). If-statements may still be necessary to cover the cases MaxK=0 and Maxk=1 where the k-loop should not be executed.
If Maxk is meant to be the last index in the zero based result matrix, the k-loop should just run up to Maxk-1.
Stuarts suggestion of using the if-function makes it a bit shorter at the price of the if-function to be evaluated multiple times (in the k-loop). But unless you intend to create vectors with millions of entries I guess this is negligible
.
Note that the sum works either way:
If you limit the computed index with:
like this:
you should get:
Success!
Luc
Thanks so much for your suggestions and explanations. Your programs are giving the kind of numbers that I expect. I also tried Luc's suggestion. I think I typed it in correctly but I am getting a "divide by zero error". He does get a numerical value but it is slightly different from the other programs. Any additional comments? (Sorry I did not post the worksheet last time, but I did this time.)
@JohnRudnicki wrote:
Thanks so much for your suggestions and explanations. Your programs are giving the kind of numbers that I expect. I also tried Luc's suggestion. I think I typed it in correctly but I am getting a "divide by zero error". He does get a numerical value but it is slightly different from the other programs. Any additional comments? (Sorry I did not post the worksheet last time, but I did this time.)
I did not experience the "divide by zero" error in the sheet you posted!? Where did you experienced that error?
Luc made a typo in the first summand. It should read k-m rather than k+1.
Luc's program only returns the last value. If you need he whole list simply add C as the last program line.
Furthermore Luc's loop still runs up to Maxk while my suggestion was to use Maxk-1 as upper limit. So he is doing one more iteration.
Thanks for the additional comments:
Hmm. The worksheet I posted was MC11 (for Luc) and I do not get the "divide by zero" error in it either. But I do get it in my original MC14 worksheet.
Strange, but from the pic alone I can't spot any calculation where a division by zero could occur.
Can you post the offended worksheet?
Next step I would do would be to use error tracing to see where MC thinks the division by zero occurs.
Find attached a the MC15 sheet with working ConcLM. I added the return statement in case Maxk=0 to avoid a k-loop running from 0 down to -1.
Also fixed ConcSB - you seem to have mixed in some obsolete parts from ConcWE there.
The first line "Maxk <-- round(Maxk)" was only thrown in by me in case the last argument supplied would not be an integer. You sure can delete this line if you can ensure that only non-negative integer values will be used as third function argument.
A also used "if Maxk<=0" and not "if Maxk = 0" to deal with negative values provided as third argument.
But of course not all possible errors are covered by doing so. The program still fails if the third argument provided is a non-real number, a string or a matrix 😉
Thanks for the additional information. and the revised worksheet. Third argument will be a positive integer. So I don't need to worry about the issues of non-real numbers, etc.
I have posted the worksheet (Concentration01) that gives the "division by zero" error.
I am having another problem presented in the other worksheet that I hope you can help with. I originally tried to write the program to give multiple values just as a test. But in practice I want to pass a single value to another program. Per your comment about Luc's program, I just eliminated the last line "C". This is fine except when Maxk = 1 and the program gives a column of two entries. I thought I could solve this by just eliminating the "stack" but this did not work. Then I fairly randomly tried a number of other possibilities (presented in the worksheet), none of which worked. Clearly, I do not know what I am doing here.
OK, this was a tricky one which took some time until I realized whats the cause for the difference.
The error occurs because Luc's attempt does not prevent the summation from 1 to 0 from being executed. It only sets the nominators of the summands used in the process to C0. The approach therefore only works because C0 is fortunately set to zero and therefore these sums, which should actually be avoided, only add zeros. That is also why I do not particularly like this approach - it would not work if C has to be initialized with a value different from zero.
So when m runs through the values 1 and 0, the last summand gives us the expression 0/0 for m=0. This is undefined, and therefore it is perfectly fine for Mathcad to issue an error message here.
In Mathcad 14/15, however, there is an option in the worksheet options to set 0/0 to be treated as 0.
"Tools" - "Worksheet Options..." then tab "Calculation"
In the sheet you posted the option 0/0 = 0 was not checked and that's the cause Mathcad treated 0/0 the correct mathematical way and threw an error 😉
ConcLM only works if this option is enabled (and if C0 is always initialized to 0). Of course it still fails for Maxk=1, which is why I included the branch before the loop in my version. This may also solve your problem in the other sheet, but I would rather prefer ConcSB over ConcLM.
According you attempts with ConcWExx in the other sheet: If you initialize C with just one value instead of 2 (like I did using the stack function) you must assure that you create a vector, not a scalar.
So I guess this is what you are trying to achieve
The last line would not be mandatory but I feel its good style to explicitly state a return value.
Find also similar SB and LM versions in the attached sheet. Personally I would settle for SB. SB also does not avoid the unwanted summations to be done, but it explicitly adds plain zeros (not only setting the nominators to zero). So this version (like the WE) also works if the option 0/0=0 is not set.
I was also curious concerning efficiency wrt calc time.
WE and SB can be considered to be equivalent. The effect with LM can probably be explained by the many calls to the external function “lim”
Added a second more streamlined variant ConcWE2.
Its easier to adopt for an initial value different than 0, also predefines the first two vector elements and uses an if branch only once to determine if more than 2 elements have to be calculated.
Its the fastest version so far - probably because it uses just one single summand in the sum rather than the sum of two.
Also added a ConcWE2vec variant which returns the full vector of values.
So you have the choice
Yes, typo. Sloppy work on my part, sorry.
The intended functionality was that every index to the C-vector that was outside of the legal range would be replaced by the region border. So all indices <0 would become 0 and those >k would become k. That way you'd have items repeating in the summation, and I guess that was not your intention.
Success!
Luc
@LucMeekes wrote:
Yes, typo. Sloppy work on my part, sorry.
The intended functionality was that every index to the C-vector that was outside of the legal range would be replaced by the region border. So all indices <0 would become 0 and those >k would become k. That way you'd have items repeating in the summation, and I guess that was not your intention.
Success!
Luc
The only situation when indices larger than k are turned to k is when k=0. So in effect invalid indices always are set to zero and fortunately C[0 was set to 0. So the superfluous items which are summed up are all zero and this approach thus returns the correct values .... once we set the worksheet calculation option that 0/0 should be treated as zero, otherwise we get the division by zero error.