Community Tip - Did you get an answer that solved your problem? Please mark it as an Accepted Solution so others with the same problem can find the answer easily. X
Is it an error in Mathcad Prime?
Odd, Valery. It seemed to work on my Prime 7.0.0.0 Trial.
Stuart
Stuart,
Not odd. The 'magic' is in the fact that Valery put an evaluation (=) after the range definition of i. That changes the range to a vector. This is a special feature of Prime.
With that evaluation your sheet shows:
The summation with a single i at its bottom, requires i to be a range; vector is not allowed.
Success!
Luc
@LucMeekes wrote:
Stuart,
Not odd. The 'magic' is in the fact that Valery put an evaluation (=) after the range definition of i. That changes the range to a vector. This is a special feature of Prime.
With that evaluation your sheet shows:
The summation with a single i at its bottom, requires i to be a range; vector is not allowed.
Success!
Luc
Ah, of course. Thanks, Luc. I definitely need those new glasses!
I did know about this "feature", but I tend to avoid putting evaluation operators at the end of definitions, precisely because of such side effects. I don't think that it's entirely clear from the rhs of the evaluation what the definition will actually assign to the variable.
IMO, for this purpose, they'd have been better off implementing a vec function that converts any argument to a vector.
I believe that I've suggested in the past that Mathcad ought to auto-iterate over vectors (or arrays, in general) in such cases. I vaguely recall having a discussion about this some time ago and there being some objections - but I can't remember what they were. I'll have to have a think about it. I vaguely recall Tom Gutman and jMG commenting ...
However, the feature request for an automatic vector product still stands. 🙂
Cheers,
Stuart
(I also wonder if min and max ought to return the first and last elements of a range ...I can think of a few uses for this capability?)
Thanks, Luc and Stuart!
But my thanks are not simple, but ironic!
Previously, I had one question, and following your response, I have two questions!
@ValeryOchkov wrote:
Thanks, Luc and Stuart!
But my thanks are not simple, but ironic!
Previously, I had one question, and following your response, I have two questions!
Затем после нескольких ваших вопросов, вы будете иметь много, много вопросов, чтобы думать! 😈
Stuart
"I did know about this "feature",":
It's not a feature. The evaluation of a range turning it into a vector is not on the published list of methods to create a vector (See Prime Help under: Vectors, Matrices, and Tables > Creating Arrays and Tables > Methods for Defining Arrays), so it's an undocumented side effect that creates problems for users.
"I tend to avoid putting evaluation operators at the end of definitions" :
I fully agree, it is a common source of problems, occasionally seen here on the forum.
"I also wonder if min and max ought to return the first and last elements of a range ...":
No, certainly not. min() and max() serve to get the lowest and highest values of an array (vector or matrix). Those are not necessarily the first and the last respectively. To get the first of a vector V you simply use V[ORIGIN and the last is had with V[last(V).
Now if last() wasn't already used to get the highest index of a Vector, I might have advocated the functions first() and last() for those element values, but alas...
Luc
<I wrote this at the time but forgot to push the Post button>
@LucMeekes wrote:
"I did know about this "feature",":
It's not a feature. The evaluation of a range turning it into a vector is not on the published list of methods to create a vector (See Prime Help under: Vectors, Matrices, and Tables > Creating Arrays and Tables > Methods for Defining Arrays), so it's an undocumented side effect that creates problems for users
I believe the traditional name for such cases is "undocumented feature". "Undocumented side-effect" sounds less ... positive. I quoted "feature" to imply that I was aware of its status.
"I also wonder if min and max ought to return the first and last elements of a range ...":No, certainly not. min() and max() serve to get the lowest and highest values of an array (vector or matrix). Those are not necessarily the first and the last respectively.
After a few hours sleep, I agree that min and max are the wrong choices for the first and last elements of a range variable. However, that's more for a technical reason than the underlying principle. What I believe should happen is:
Given that:
then:
first(rv) should return the start value of the range.
last(rv) should return the stop value of the range.
<suggest name, second?> should return the second value of the range.
min(rv) should return the minimum value of the evaluated sequence.
max(rv) should return the maximum value of the evaluated sequence.
For. rv:=0,1..π, I'd expect:
first(rv)= 0, min(rv) = 0; last(rv) = 3.141, max(rv) = 6.
Under the symbolic processor, I'd expect:
last(rv)→π.
I'd also like a function rng2vec that, analogously to str2vec, returns a vector containing start, step, and stop. The name could be improved, as it could be interpreted as meaning it expands the range. It goes without saying, but I'll say it anyway, that there should be an inverse function vec2rng that creates a range from a 3-vector.
And while I'm high on featurehol, I'd also like range types to be a bit smarter and:
Oh, and if it helps overcome any problems with using vectors as indices, I'd like the sequence to be a specific data type, separate from the vector or array. A sequence should be an extension of a range in terms of appearance and use. That is, enter a list of values separated by commas (and possibly semicolons); (start,step..stop) type ranges should be enclosed in parentheses to remove ambiguity).
Plus, I want general sequences restored in for loops, and sequences made into a proper data type that can be assigned to variables.
"I also wonder if min and max ought to return the first and last elements of a range ...":To get the first of a vector V you simply use V[ORIGIN and the last is had with V[last(V).
I, like you, have a library of Prime Express functions that I use to get around the lack of programming. Some of them are based upon, but not identical to, the functions that can be found in many functional programming languages, such as Haskell, or programming languages that have support for functional programming. I do, however, try to take into account that Mathcad Prime is not a true functional programming language (especially in its Express form) and that Mathcad has its differences in how data is handled.
I use head and tail to do what you suggest (a break with many conventions for tail). head(a) returns a non-array unchanged, the value of the first element of a vector, and the first row of a non-vector array. tail(a) returns "empty" for a non-array, the value of the last element of a vector, and the last row of a non-vector array.
I use first(a,n) and last(a,n) to return the first and last, respectively, n rows of array a.
Now if last() wasn't already used to get the highest index of a Vector, I might have advocated the functions first() and last() for those element values, but alas...
Pardon me whilst I recover from an outpouring of hysterical laughter. 🤣
Given Mathsoft's and PTC's penchant for breaking things, I have no problems whatsoever in changing the meaning of last - breaking sequences in for loops is an apposite example.
Compared to some of the major changes that have been made to Mathcad over the years, some requiring significant rewrites, I'll hazard that this change should be almost trivial for most users. I've always found the name unintuitive for its purpose, anyway, and hardly ever use it.
It would (should!) be easy enough to change last upon reading older worksheets to some suitable new name (eg, end, lastindex) and annotating the change. Indeed, I vaguely recall discussion along the lines of just missing the value out and Mathcad inferring that the author means the last element. I normally use -1 in my functions (in general, being a zero-index aficionado, I use negative numbers to count backward from the end of an array dimension).
Stuart
Note that a range is specific data type in the Mathcad Prime 7 XML worksheet format.
<ml:define>
<ml:id xml:space="preserve" labels="VARIABLE">k</ml:id>
<ml:range>
<ml:real>0</ml:real>
<ml:apply>
<ml:minus/>
<ml:id xml:space="preserve" labels="VARIABLE" label-is-contextual="true">n</ml:id>
<ml:real>1</ml:real>
</ml:apply>
</ml:range>
</ml:define>
Interestingly, the word sequence crops up for a function's parameter list, which is one of the potential uses I had in mind for sequences (primarily as a means of implementing variable number parameter lists).
<ml:define>
<ml:function>
<ml:id xml:space="preserve" labels="VARIABLE">ints</ml:id>
<ml:boundVars>
<ml:id xml:space="preserve" labels="VARIABLE">n</ml:id>
</ml:boundVars>
</ml:function>
<ml:apply>
<ml:id xml:space="preserve" labels="FUNCTION" label-is-contextual="true">matrix</ml:id>
<ml:sequence>
<ml:id xml:space="preserve" labels="VARIABLE" label-is-contextual="true">n</ml:id>
<ml:real>1</ml:real>
<ml:id xml:space="preserve" labels="FUNCTION" label-is-contextual="true">max</ml:id>
</ml:sequence>
</ml:apply>
</ml:define>