Just stumbled across a bug in some old code of mine where to check if an array was empty or not I just wrote:
if my_array
...(do stuff)
end
instead of using isempty or something like that.
What I have discovered is that "if my_array" returns 0 only if the array is indeed empty OR if one or more of the components in the array are 0.
Is this expected? What exactly is going on? Is matlab performing an and operation on all the elements?
Many thanks
That is exactly the behaviour as it is documented:
An evaluated expression is true when the result is nonempty
and contains all nonzero elements (logical or real numeric). Otherwise,
the expression is false.
Related
An abstract question, not related to any particular language:
If I have a function as follows
min(int, int) :: int
which returns the smallest value in an array, and
concat([int], [int]) :: [int]
which combines two arrays, how should I write a function like
minInArray([int]) :: Int
which returns the smallest element in an array, but where the ouput could be chained like so, even with an empty input array:
min(minInArray(array1), minInArray(array2)) == minInArray(concat(array1, array2))
In other words, is there any commonly-used neutral element which minInArray could return on empty input, which wouldn't mess up min()?
One option would be to return some neutral value like null or NaN if the array has no elements, and then if the min() function is run and one of the arguments is the neutral value, then you just return the min of the other array. Another option would be to return the closest value the language has to +Infinity if the array is empty; this works and does not require modifying min(), but does have the side effect of returning an infinite value sometimes when the minInArray() function is called. This infinite value could work as a truly neutral value that works with the default min() function, but it may cause some confusion if the minimum value in an array really is infinite.
minInArray(arr1) to return null if arr1 is empty.
min() should return only non-null values over null. Meaning min() will only return null if both parameters are null. Otherwise, it will return the minimum non-null value.
While thinking about the issue we've come to seemingly the only solution possible:
if an array is empty - we should return the maximum possible value for int to satisfy the condition.
Not that nice actually...
Just to add some perspectives (not that this is a duplicate of the listed questions) -
All of these throw errors of some kind when asked to calculate min of an empty list or array: Java, Scala, Python, numpy, Javascript, C#. Probably more, but that's as far as I looked. I'm sure there are some that don't, but I'd expect most of those to be languages which have traded understandability and clarity for speed.
This question is about a specific language, but has answers relevant to all languages.
Note here how one can get around the issue in something like Python.
For Haskell in particular, note the advice in this question.
And lastly here's a response for a more general case of your question.
In general, it is always most important for code to work, but a close second to that is it must be understandable to humans. Perhaps it doesn't matter for your current project, if you'll be the only one dealing with that function, but the last thing I'd expect when calling a 'get_minimum' function, is Int.MAX.
I understand it makes the coding simple, but I'd urge you to beware of code that is easy to write and tricky to understand. A little more time spent making the code easy to read, with as much as possible having an immediately obvious meaning, will always save much more time later on.
The following is the code, actually, #arr0 and #arr1 are not equal, even after sorting, they are not equal, but why "eq" will be printed? at first, I thought about the return value of sort funtion, but it did return an array,so what's the reason?
my #arr0 = (1,2);
my #arr1 = ("a","b");
if ( (sort #arr0) ~~ (sort #arr1) ) {
print "eq\n";
};
[Note: All links to documentation in this answer are to the documentation for version 5.12.1. This ensures the answer is useful for the original poster - it might make it less useful for other people.]
It's important to realise that arrays and lists are not the same. This is one case where the behaviour is different.
It's also important to read the documentation for sort(), which starts by saying:
In list context, this sorts the LIST and returns the sorted list value. In scalar context, the behaviour of sort() is undefined.
There are two important things there. Firstly, in list context, sort() returns a list, not an array. And secondly, in scalar context, its behaviour is undefined.
Now let's look at the smartmatch documentation. That's a big table of left- and right-operands that I won't reproduce here. But note that it doesn't mention lists at all. So, almost certainly, smartmatch is calling sort() in scalar context and doing either a string or numeric comparison
on the results (one of the last few rows in the table).
But we know that sort()'s behaviour in scalar context is undefined. So who knows what value smartmatch is comparing. But I guess that whatever random value it is returning, it is (at least) returning the same random value for both of your lists. Which means they appear to be equal.
As you've said in a comment, it works when you save the sorted results in arrays and pass arrays to smartmatch. That's because arrays have special behaviours defined in the smartmatch table.
Arrays are not lists
Don't call sort() in scalar context
Update: As ThisSuitIsNotBlack mentions in the comments, smartmatch has been rather unstable since it was introduced in Perl 5.10. Its behaviour has been tweaked in pretty much every Perl release since then and its final form still isn't completely agreed. For that reason, I strongly discourage you from using it at all.
How does one access an element of an array that is returned from a function? For example, shape() returns an array of integers. How does one compare an element of that array to an integer? The following does not compile:
integer :: a
integer, dimension(5) :: b
a = 5
if (a .eq. shape(b)) then
print *, 'equal'
end if
The error is:
if (a .eq. shape(c)) then
1
Error: IF clause at (1) requires a scalar LOGICAL expression
I understand that this is because shape(c) returns an array. However, accessing an element of the array does not appear to be possible like so: shape(c)(1)
Now if I add these two lines:
integer, dimension(1) :: c
c = shape(b)
...and change the if clause to this:
if (a .eq. c(1)) then
... then it works. But do I really have to declare an extra array variable to hold the return value of shape(), or is there some other way to do it?
Further to the answers that deal with SHAPE and logical expressions etc, the general answer to your question "How does one access an element of an array that is returned from a function?" is
you assign the expression that has the function reference to an array variable, and then index that array variable.
you use the expression that has the function reference as an actual argument to a procedure that takes a dummy array argument, and does the indexing for you.
Consequently, the general answer to your last questions "But do I really have to declare an extra array variable to hold the return value of shape(), or is there some other way to do it?" is "Yes, you do need to declare another array variable" and hence "No, there is no other way".
(Note that reasonable optimising compilers will avoid the need for any additional memory operations/allocations etc once they have the result of the array function, it's really just a syntax issue.)
The rationale for this particular aspect of language design is sometimes ascribed to a need to avoid syntax ambiguity and confusion for array function results that are of character type (they could potentially be indexed and/or substringed - how do you tell what was intended?). Others think it was done this way just to annoy C programmers.
Instead of using shape(array), I would use size(array).
Note that this will return an integer indicating how many elements there are in ALL dimensions, unless you specify the DIM attribute, in which case it will return only the number of elements in the specified dimension.
Take a look at the gfortran documentation:
http://gcc.gnu.org/onlinedocs/gfortran/SIZE.html.
Also, look up lbound and ubound.
Note that the expression
a == shape(b)
returns a rank-1 array of logicals and the if statement requires that the condition reduce to a scalar logical expression. You could reduce the rank-1 array to a scalar like this:
if (all(a == shape(b)))
This is certainly not a general replacement for the syntactically-invalid application of array indexing to an array-returning function such as shape(b)(1).
It is possible even without the intermediate variable using ASSOCIATE:
real c(3,3)
associate (x=>shape(c))
print *,x(1),x(2)
end associate
end
Why unpack({0,1,1})==unpack({0,0,1}) are the same?
How to compare and proof them and proof they are different in Lua?
When a function call appears inside an expression, its return value is adjusted to one result. table.unpack({0,1,1}) == table.unpack({0,0,1}) is true because their first return value are both 0.
To compare them, iterate the tables and compare elements instead. table.pack might be helpful.
unpack is now table.unpack since Lua 5.2
I am trying to use numpy_where to find the index of a particular value. Though I have searched quite a bit on the web including stackoverflow I did not find a simple 1D example.
ar=[3,1,4,8,2,1,0]
>>> np.where(ar==8)
(array([], dtype=int64),)
I expected np.where(ar==8) to return me the index/location of 8 in the the array.
What am I doing wrong? Is it something in my array?
Thanks
This is a really good example of how the range of variable types in Python and numpy can be confusing for a beginner. What's happening is [3,1,4,8,2,1,0] returns a list, not an ndarray. So, the expression ar == 8 returns a scalar False, because all comparisons between list and scalar types return False. Thus, np.where(False) returns an empty array. The way to fix this is:
arr = np.array([3,1,4,8,2,1,0])
np.where(arr == 8)
This returns (array([3]),). There's opportunity for further confusion, because where returns a tuple. If you write a script that intends to access the index position (3, in this case), you need np.where(arr == 8)[0] to pull the first (and only) result out of the tuple. To actually get the value 3, you need np.where(arr == 8)[0][0] (although this will raise an IndexError if there are no 8's in the array).
This is an example where numeric-specialized languages like Matlab or Octave are simpler to use for newbies, because the language is less general and so has fewer return types to understand.