In VB6 it is possible to prepand array identifiers with an empty array index. For example:
Dim x(0 To 20) As Integer
x(0) = 1
Debug.Print x(0)
Debug.Print x()(0)
The debug statements appear to the same thing, even though an empty index is given to the array before the index in the last statement. Does anyone know what this is and why this works?
Does anyone know what this is and why this works?
It’s a “bug” in the compiler: for reasons of syntactical consistency with the declaration, references to an array x may also be written as x(); thus, it is possible to write the following code:
Dim x() As Integer
x() = SomeFunctionReturningAnArray()
Well, some programmers think this is more consistent than writing x = …. (I thought so, too, for a time.) That you can use it in front of dereferencing the array is simply a hole in the syntax validation, though.
Related
I'm trying to change the number of items in array, over which a for loop is running, during the for loop, with the objective that this changes the number of loops. In a very simplified version, the code would look something like this:
var loopArray: [Int] = []
loopArray.append(1)
loopArray.append(2)
loopArray.append(3)
loopArray.append(4)
loopArray.append(5)
for x in 0..<Int(loopArray.count) {
print(x)
if x == 4 {
loopArray.append(6)
}
}
When running this code, 5 numbers are printed, and while the number 6 is added to the Array, the loopArray.count does not seem to update. How can I make the .count dynamic?
This is a very simplified example, in the project I'm working on, appending numbers to the array depends on conditions that may or may not be met.
I have looked for examples online, but have not been able to find any similar cases. Any help or guidance is much appreciated.
sfung3 gives the correct way to do what you want, but I think there needs to be a bit of explanation as to why your solution doesn't work
The line
for x in 0..<Int(loopArray.count)
only evaluates loopArray.count once, the first time it is hit. This is because of the way for works. Conceptually a for loop iterates through the elements of a sequence. The syntax is something like
for x in s
where
s is a sequence, give it type S
x is a let constant (you can also make it a var but that is not relevant to the current discussion) with type S.Element
So the bit after the in is a sequence - any sequence. There's nothing special about the use of ..< here, it's just a convenient way to construct a sequence of consecutive integers. In fact, it constructs a Range (btw, you don't need the cast to Int, Array.count is already an Int).
The range is only constructed when you first hit the loop and it's effectively a constant because Range is a value type.
If you don't want to use Joakim's answer, you could create your own reference type (class) that conforms to Sequence and whose elements are Int and update the upper bound each time through the loop, but that seems like a lot of work to avoid a while loop.
you can use a while loop instead of a for loop.
var i = 0
while i < loopArray.count {
print(i)
if i == 4 {
loopArray.append(6)
}
i += 1
}
which prints
0 1 2 3 4 5
I have an array arr in fortran going from 1 to n where I need to test each element against the elements preceding and succeeding (i.e. i against i-1 and i+1) - the problem being elements 1 and n that have n or 1 as predecessor or successor, respectively (i.e. it loops).
Instead of testing the first and last elements separately, I'd rather run a loop like:
do i=1,n
call testi(i-1,i,i+1)
end do
and define a pointer (in order to not use a dummy array and twice the memory) like
arrpointer(0) => arr(n)
arrpointer(1:n) => arr(1:n)
arrpointer(n+1) => arr(1)
to "simulate" the loop in my array. (Note that each array element is a vector - arr(i)%vec(1:m) )
The above does not work as each new definition of the pointer will overwrite the previous. So the question arises:
Is there any way to actually add an element to a pointer array without deleting the previous definitions?
PS:
As current workaround, I use an allocatable type array with the pointers:
type :: pointerarray
real, pointer :: elementpointer(:)
end type pointerarray
type(pointerarray), allocatable :: arrpointer(:)
arrpointer(0)%elementpointer => arr(n)
do i=1,n
arrpointer(i)%elementpointer => arr(i)
end do
arrpointer(n+1)%elementpointer => arr(1)
while replacing the loop as below does not work:
arrpointer(1:n)%elementpointer => arr(1:n)
However there might be a simpler way of which I am not aware, as type arrays for the pointers again make the code not as nicely readable.
I don't think there's a way to do this with pointers the way you envision. Instead, I recommend using an integer array dimensioned 0:N+1 that map to the desired 1:N range. For example:
integer :: i(0:N+1), j
real :: a(N)
! -- Setup
do j=1,N
i(j) = j
enddo
i(0) = N
i(N+1) = 1
! -- Then you can do:
do j=1,N
! call mysub(a(i(j-1)), a(i(j)), a(i(j+1)))
enddo
Alternatively, you could use a function to define i(j).
I don't have Fortran on this machine so haven't tested this. It's also not entirely clear what OP's testi routine does. So, this is not a complete answer, but might provide some useful (or useless) hints at a pointerless solution.
Don't forget the intrinsic function chsift. One way to perform, say, a one-sided difference calculation on an array would be to write
arrdiff = arr - chsift(arr,1)
cshift shifts elements from one end of the array to the other unlike its cousin eoshift which performs an end-off shift. Of course chsift is likely to require the creation of a temporary of the same size as the array (in theory it could be done without a temporary, in practice it always seems to use one) so may be unappealing on performance and memory usage grounds.
This is rather easy question or maybe too easy question. But i tried to find the way to done these already and could not find even in GNUplot document. Might be my mistake or misunderstood something about array concept in GNUplot. My question is How to define and access array in GNUplot?
Please just provide easy example of array declaration, assign value of array over loop. i think that's enough and i think this will be useful for other people too.
If you are using Gnuplot 5.1 or superior and need a 1-d array, you simply define the array with size N, remembering that the indices go from 1 to N:
gnuplot> array A[3] #Array definition
gnuplot> A[1]=2
gnuplot> A[3]=4
gnuplot> print A[1]
2
gnuplot> print A #Print the array, with empty A[2]
[2,,4]
If you need more than one dimension or are using previous versions of Gnuplot, you can do the following:
Since there are no vector variables in previous versions of Gnuplot, two functions can be defined to get and set values to a behind the scenes variable whose name include the index. The functions are:
aGet(name, i) = value(sprintf("_%s_%i", name, i))
aSet(name, i, value) = sprintf("_%s_%i = %.16e", name, i, value)
To assign and retrieve values on the array A you do
eval aSet("A",2,3)
print aGet("A",2)
What these functions do is to access a variable called _A_2.
You can build similar function to work with matrices:
mGet(name, i, j) = value(sprintf("_%s_%i_%i", name, i, j))
mSet(name, i, j, value) = sprintf("_%s_%i_%i = %.16e", name, i, j, value)
(This answer will be obsolete with the next stable gnuplot release, as the 5.1 development tree now has native support for array variables.)
(The "splot" command in gnuplot uses the keyword "array" to define the size of NxM matrix that contains function values for a 3D plot. Nothing to do with array variables.)
Arrays like what a programmer knows from C, Pascal, Python, etc. do not exist in gnuplot today (gp5.0). They might get implemented one day, because they'd be highly useful to plot a family of curves with arbitrary (e.g. fitted) parameters.
If you are desperate about arrays in gnuplot, you can (ab)use the word() function (and other string functions) to achieve a somewhat limited substitute. It's also a bit cumbersome:
array = ""
f(a,x) = a*x
do for [i=1:5] {array = array.sprintf(" %.3f",i+rand(0)) }
print "array = ".array
set xr [0:]; set yr [0:30]
plot for [i=1:5] f(word(array,i),x) title word(array,i)." x"
This example writes a set of random numbers to a string variable named "array", and afterwards uses it to plot five linear functions that use the numbers in "array" for their slope. It's handy here that gnuplot autopromotes strings to numerics if used e.g. in an equation.
Inspired by #Karl 's answer, it looks even more like an array when putting the word function into another function:
array(n) = word("1 2 3 4 5 6 7 8 9", n)
print array(3)
This prints 3. So the indexing is one-based.
"Multiply" the array by 2:
print (b="", sum[i=1:9](b=b.(array(i)*2)." ", 0), b)
This prints 2 4 6 8 10 12 14 16 18. Here the sum function is (ab)used to loop over the array and its result is ignored.
And here is shorter, through less generic variant of #bmello's answer:
A_1=1.1; A_2=2.2; A_3=3.3
A(i) = value("A_".i)
print A(3)
For me it feels more intuitiv. The underscore _ can be seen simply as the set function. Also it is not limited to integer indices. Strings are also possible which give some dictionary-like behaviour.
OP UPDATE: Note that in the latest version of Julia (v0.5), the idiomatic approach to answering this question is to just define mysquare(x::Number) = x^2. The vectorised case is covered using automatic broadcasting, i.e. x = randn(5) ; mysquare.(x). See also the new answer explaining dot syntax in more detail.
I am new to Julia, and given my Matlab origins, I am having some difficulty determining how to write "good" Julia code that takes advantage of multiple dispatch and Julia's type system.
Consider the case where I have a function that provides the square of a Float64. I might write this as:
function mysquare(x::Float64)
return(x^2);
end
Sometimes, I want to square all the Float64s in a one-dimentional array, but don't want to write out a loop over mysquare everytime, so I use multiple dispatch and add the following:
function mysquare(x::Array{Float64, 1})
y = Array(Float64, length(x));
for k = 1:length(x)
y[k] = x[k]^2;
end
return(y);
end
But now I am sometimes working with Int64, so I write out two more functions that take advantage of multiple dispatch:
function mysquare(x::Int64)
return(x^2);
end
function mysquare(x::Array{Int64, 1})
y = Array(Float64, length(x));
for k = 1:length(x)
y[k] = x[k]^2;
end
return(y);
end
Is this right? Or is there a more ideomatic way to deal with this situation? Should I use type parameters like this?
function mysquare{T<:Number}(x::T)
return(x^2);
end
function mysquare{T<:Number}(x::Array{T, 1})
y = Array(Float64, length(x));
for k = 1:length(x)
y[k] = x[k]^2;
end
return(y);
end
This feels sensible, but will my code run as quickly as the case where I avoid parametric types?
In summary, there are two parts to my question:
If fast code is important to me, should I use parametric types as described above, or should I write out multiple versions for different concrete types? Or should I do something else entirely?
When I want a function that operates on arrays as well as scalars, is it good practice to write two versions of the function, one for the scalar, and one for the array? Or should I be doing something else entirely?
Finally, please point out any other issues you can think of in the code above as my ultimate goal here is to write good Julia code.
Julia compiles a specific version of your function for each set of inputs as required. Thus to answer part 1, there is no performance difference. The parametric way is the way to go.
As for part 2, it might be a good idea in some cases to write a separate version (sometimes for performance reasons, e.g., to avoid a copy). In your case however you can use the in-built macro #vectorize_1arg to automatically generate the array version, e.g.:
function mysquare{T<:Number}(x::T)
return(x^2)
end
#vectorize_1arg Number mysquare
println(mysquare([1,2,3]))
As for general style, don't use semicolons, and mysquare(x::Number) = x^2 is a lot shorter.
As for your vectorized mysquare, consider the case where T is a BigFloat. Your output array, however, is Float64. One way to handle this would be to change it to
function mysquare{T<:Number}(x::Array{T,1})
n = length(x)
y = Array(T, n)
for k = 1:n
#inbounds y[k] = x[k]^2
end
return y
end
where I've added the #inbounds macro to boost speed because we don't need to check the bound violation every time — we know the lengths. This function could still have issues in the event that the type of x[k]^2 isn't T. An even more defensive version would perhaps be
function mysquare{T<:Number}(x::Array{T,1})
n = length(x)
y = Array(typeof(one(T)^2), n)
for k = 1:n
#inbounds y[k] = x[k]^2
end
return y
end
where one(T) would give 1 if T is an Int, and 1.0 if T is a Float64, and so on. These considerations only matter if you want to make hyper-robust library code. If you really only will be dealing with Float64s or things that can be promoted to Float64s, then it isn't an issue. It seems like hard work, but the power is amazing. You can always just settle for Python-like performance and disregard all type information.
As of Julia 0.6 (c. June 2017), the "dot syntax" provides an easy and idiomatic way to apply a function to a scalar or an array.
You only need to provide the scalar version of the function, written in the normal way.
function mysquare{x::Number)
return(x^2)
end
Append a . to the function name (or preprend it to the operator) to call it on every element of an array:
x = [1 2 3 4]
x2 = mysquare(2) # 4
xs = mysquare.(x) # [1,4,9,16]
xs = mysquare.(x*x') # [1 4 9 16; 4 16 36 64; 9 36 81 144; 16 64 144 256]
y = x .+ 1 # [2 3 4 5]
Note that the dot-call will handle broadcasting, as in the last example.
If you have multiple dot-calls in the same expression, they will be fused so that y = sqrt.(sin.(x)) makes a single pass/allocation, instead of creating a temporary expression containing sin(x) and forwarding it to the sqrt() function. (This is different from Matlab/Numpy/Octave/Python/R, which don't make such a guarantee).
The macro #. vectorizes everything on a line, so #. y=sqrt(sin(x)) is the same as y = sqrt.(sin.(x)). This is particularly handy with polynomials, where the repeated dots can be confusing...
I'm seeing an issue when I try and reference an object property after having used a dot notation to apply a method.
it only occurs when I try to index the initial object
classdef myclassexample
properties
data
end
methods
function obj = procData(obj)
if numel(obj)>1
for i = 1:numel(obj)
obj(i) = obj(i).procData;
end
return
end
%do some processing
obj.data = abs(obj.data);
end
end
end
then assigning the following
A = myclassexample;
A(1).data= - -1;
A(2).data = -2;
when calling the whole array and collecting the property data it works fine
[A.procData.data]
if i try and index A then i only get a scalar out
[A([1 2]).procData.data]
even though it seems to do fine without the property call
B = A([1 2]).procData;
[B.data]
any ideas?
I would definitely call this a bug in the parser; A bug because it did not throw an error to begin with, and instead allowed you to write: obj.method.prop in the first place!
The fact that MATLAB crashed in some variations of this syntax is a serious bug, and should definitely be reported to MathWorks.
Now the general rule in MATLAB is that you should not "index into a result" directly. Instead, you should first save the result into a variable, and then index into that variable.
This fact is clear if you use the form func(obj) rather than obj.func() to invoke member methods for objects (dot-notation vs. function notation):
>> A = MyClass;
>> A.procData.data % or A.procData().data
ans =
[]
>> procData(A).data
Undefined variable "procData" or class "procData".
Instead, as you noted, you should use:
>> B = procData(A): % or: B = A.pocData;
>> [B.data]
FWIW, this is also what happens when working with plain structures and regular functions (as opposed to OOP objects and member functions), as you cannot index into the result of a function call anyway. Example:
% a function that works on structure scalar/arrays
function s = procStruct(s)
if numel(s) > 1
for i=1:numel(s)
s(i) = procStruct(s(i));
end
else
s.data = abs(s.data);
end
end
Then all the following calls will throw errors (as they should):
% 1x2 struct array
>> s = struct('data',{1 -2});
>> procStruct(s).data
Undefined variable "procStruct" or class "procStruct".
>> procStruct(s([1 2])).data
Undefined variable "procStruct" or class "procStruct".
>> feval('procStruct',s).data
Undefined variable "feval" or class "feval".
>> f=#procStruct; f(s([1 2])).data
Improper index matrix reference.
You might be asking yourself why they decided to not allow such syntax. Well it turns out there is a good reason why MATLAB does not allow indexing into a function call (without having to introduce a temporary variable that is), be it dot-indexing or subscript-indexing.
Take the following function for example:
function x = f(n)
if nargin == 0, n=3; end
x = magic(n);
end
If we allowed indexing into a function call, then there would be an ambiguity in how to interpret the following call f(4):
should it be interpreted as: f()(4) (that is call function with no arguments, then index into the resulting matrix using linear indexing to get the 4th element)
or should it interpreted as: f(4) (call the function with one argument being n=4, and return the matrix magic(4))
This confusion is caused by several things in the MATLAB syntax:
it allows calling function with no arguments simply by their name, without requiring the parentheses. If there is a function f.m, you can call it as either f or f(). This makes parsing M-code harder, because it is not clear whether tokens are variables or functions.
parentheses are used for both matrix indexing as well as function calls. So if a token x represents a variable, we use the syntax x(1,2) as indexing into the matrix. At the same time if x is the name of a function, then x(1,2) is used to call the function with two arguments.
Another point of confusion is comma-separated lists and functions that return multiple outputs. Example:
>> [mx,idx] = max(magic(3))
mx =
8 9 7
idx =
1 3 2
>> [mx,idx] = max(magic(3))(4) % now what?
Should we return the 4th element of each output variables from MAX, or 4th element from only the first output argument along with the full second output? What about when the function returns outputs of different sizes?
All of this still applies to the other types of indexing: f()(3)/f(3), f().x/f.x, f(){3}/f{3}.
Because of this, MathWorks decided avoid all the above confusion and simply not allow directly indexing into results. Unfortunately they limited the syntax in the process. Octave for example has no such restriction (you can write magic(4)(1,2)), but then again the new OOP system is still in the process of being developed, so I don't know how Octave deals with such cases.
For those interested, this reminds me of another similar bug with regards to packages and classes and directly indexing to get a property. The results were different whether you called it from the command prompt, from a script, or from a M-file function...