Redefining a value at index of recursive lazy array - arrays

I'm having a <<loop>> error for trying to redefine a value on an already defined index.
Simplified example:
ghci > let axs = array (1,5) [(1,1),(2,2),(3,3),(4,4),(5,5),(1, 1 + axs!1)]
ghci > axs
array (1,5) [(1,^CInterrupted.
This will loop. I'm assuming that the lazy nature of Data.Array is what is causing that behaviour.
This, on the other hand, won't loop and will work as expected (redefines index 1).
ghci > array (1,5) [(1,1),(2,2),(3,3),(4,4),(5,5),(1,6)]
array (1,5) [(1,6),(2,2),(3,3),(4,4),(5,5)]
Is there any way to redefine an indexed value with recursion to self?
I'm assuming I need to force the evaluation of the wanted index to be able to "update" the value again using the previous one.
Is that possible or I shouldn't/can't use the array this way?

In a recursive definition, the meaning of the thing being defined on the right is its final value. So
x = x + 1
will be an infinite loop. In an array definition (in GHC), the value of an index is its last appearance, so
axs = array (1,5) [(1,1),(2,2),(3,3),(4,4),(5,5),(1, 1 + axs!1)]
is the same as
axs = array (1,5) [(2,2),(3,3),(4,4),(5,5),(1, 1 + axs!1)]
the important part of this is
axs' = array (1,1) [(1, 1 + axs!1)]
which is the same idea as
x = 1 + x
Note that "redefinition" in array definitions is not permitted by the Haskell standard at all, and should always loop or throw an exception. GHC allows it, but that is not strictly is agreement with the standard.
Even in GHC the "redefinition" is not imperative. You are not one by one setting the values in the array. Rather, an array definition is a declarative specification for the entire array.
If you want an imperative approach to constructing arrays, use the st monad
This is not tested:
arr = runSTArray $ do
retArr <- newArray (1,5) [(1,1),(2,2),(3,3),(4,4),(5,5)]
curVal <- readArray retArr 1
writeArray retArr 1 (curVal + 1)
retArr

Related

Filling a row and columns of a ndarray with a loop

I'm starting with Python and I have a basic question with "for" loop
I have two array which contains a values of a same variables:
A = data_lac[:,0]
In the first array, I have values of area and in the second on, values of mean depth.
I would like to find a way to automatize my calculation with different value of a parameter. The equation is the following one:
g= (np.sqrt(A/pi))/n
Here I can calculte my "g" for each row. Now I want to have a loop with differents values of "n". I did this:
i=0
while i <= len(A)-1:
for n in range(2,6):
g[i] = (np.sqrt(A[i]/pi))/n
i += 1
break
In this case, I just have one column with the calculation for n = 2 but not the following one. I tried to add a second dimension to my array but I have an error message saying that I have too many indices for array.
In other, I would like this array:
g[len(A),5]
g has 5 columns each one calculating with a different "n"
Any tips would be very helpful,
Thanks
Update of the code:
data_lac=np.zeros((106,7))
data_lac[:,0:2]=np.loadtxt("/home...", delimiter=';', skiprows=1, usecols=(0,1))
data_lac[:,1]=data_lac[:,1]*0.001
#Initialisation
A = data_lac[:,0]
#example for A with 4 elements
A=[2.1, 32.0, 4.6, 25]
g = np.zeros((len(A),))
I believe you share the indexes within both loops. You were increasing the i (index for the upper while loop) inside the inner for loop (which index with n).
I guess you have A (1 dim array) and you want to produce G (2 dim array) with size of (Len(A, 5))
I am not sure I'm fully understand your require output but I believe you want something like:
i=0
while i <= len(A)-1:
for n in range(2,6):
g[i][n-2] = (np.sqrt(A[i]/pi))/n # n-2 is to get first index as 0 and last as 4
i += 1 # notice the increace of the i is for the upper while loop
break
Important - remember that in python indentation means a lot -> so make sure the i +=1 is under the while scope and not indent to be inside the for loop
Notice - G definition should be as:
g = np.zeros((len(A),4), dtype=float)
The way you define it (without the 4) cause it to be 1 dim array and not 2-dim

Fill a vector in Julia with a repeated list

I would like to create a column vector X by repeating a smaller column vector G of length h a number n of times. The final vector X will be of length h*n. For example
G = [1;2;3;4] #column vector of length h
X = [1;2;3;4;1;2;3;4;1;2;3;4] #ie X = [G;G;G;G] column vector of
length h*n
I can do this in a loop but is there an equivalent to the 'fill' function that can be used without the dimensions going wrong. When I try to use fill for this case, instead of getting one column vector of length h*n I get a column vector of length n where each row is another vector of length h. For example I get the following:
X = [[1,2,3,4];[1,2,3,4];[1,2,3,4];[1,2,3,4]]
This doesn't make sense to me as I know that the ; symbol is used to show elements in a row and the space is used to show elements in a column. Why is there the , symbol used here and what does it even mean? I can access the first row of the final output X by X[1] and then any element of this by X[1][1] for example.
Either I would like to use some 'fill' equivalent or some sort of 'flatten' function if it exists, to flatten all the elements of the X into one column vector with each entry being a single number.
I have also tried the reshape function on the output but I can't get this to work either.
Thanks Dan Getz for the answer:
repeat([1, 2, 3, 4], outer = 4)
Type ?repeat at the REPL to learn about this useful function.
In older versions of Julia, repmat was an alternative, but it has now been deprecated and absorbed into repeat
As #DanGetz has pointed out in a comment, repeat is the function you want. From the docs:
repeat(A, inner = Int[], outer = Int[])
Construct an array by repeating the entries of A. The i-th element of inner specifies the number of times that the individual entries of the i-th dimension of A should be repeated. The i-th element of outer specifies the number of times that a slice along the i-th dimension of A should be repeated.
So an example that does what you want is:
X = repeat(G; outer=[k])
where G is the array to be repeated, and k is the number of times to repeat it.
I will also attempt to answer your confusion about the result of fill. Julia (like most languages) makes a distinction between vectors containing numbers and numbers themselves. We know that fill(5, 5) produces [5, 5, 5, 5, 5], which is a one-dimensional array (a vector) where each element is 5.
Note that fill([5], 5), however, produces a one-dimensional array (a vector) where each element is [5], itself a vector. This prints as
5-element Array{Array{Int64,1},1}:
[5]
[5]
[5]
[5]
[5]
and we see from the type that this is indeed a vector of vectors. That of course is not the same thing as the concatenation of vectors. Note that [[5]; [5]; [5]; [5]; [5]] is syntax for concatenation, and will return [5, 5, 5, 5, 5] as you might expect. But although ; syntax (vcat) does concatenation, fill does not do concatenation.
Mathematically (under certain definitions), we may imagine R^(kn) to be distinct (though isomorphic to) from (R^k)^n, for instance, where R^k is the set of k-tuples of real numbers. fill constructs an object of the latter, whereas repeat constructs an object of the former.
As long as you are working with 1-dimensional arrays (Vectors)...
X=repmat(G,4) should do it.
--
On another note, Julia makes no distinction between row and column vector, they are both one-dimensional arrays.
[1,2,3]==[1;2;3] returns true as they are both 3-element Array{Int64,1} or vectors (Array{Int,1} == Vector{Int} returns true)
This is one of the differences between Matlab and Julia...
If, for some specific reason you want to do it, you can create 2-dimensional Arrays (or Matrices) with one of the dimensions equal to 1.
For example:
C = [1 2 3 4] will create a 1x4 Array{Int64,2} the 2 there indicates the dimensions of the Array.
D = [1 2 3 4]' will create a 4x1 Array{Int64,2}.
In this case, C == D returns false of course. But neither is a Vector for Julia, they are both Matrices (Array{Int,2} == Matrix{Int} returns true).

Fortran 90 array subsets

I am trying to read some Fortran code but there is something I can't understand with array subsets operations like this one
Assume n = 3
And the arrays
INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(12)
REAL(KIND=dp) :: P(n+1),P0(n)
what does this line exactly do?
DO i=1,n-1
…..
P(3:i+2) = P(3:i+2) - i*P0(1:i) / (i+1)
….
END DO
Is it a nested loop? Like j from 3 to i+2 for P and k from 1 to i for P0?
Thanks in advance.
Take the line
P(3:i+2) = P(3:i+2) - i*P0(1:i) / (i+1)
and replace i with 1 (the first value it takes in the do loop)
P(3:3) = P(3:3) - 1*P0(1:1) / 2
On the lhs you have a slice (or section) of array P from element 3 to element 3, so in this case just one element -- but still an array slice not a scalar. This is updated by subtracting 1 times the (same sized) slice of array P0 and divided by 2.
It's a bit more interesting in the next iteration, with i==2 and
P(3:4) = P(3:4) - 2*P0(1:2) / 3
where the array slices are now 2 elements each. The operations on array slices are applied on corresponding elements from each array so this statement is approximately equivalent to the two statements
P(3) = P(3) - 2*P0(1) / 3
P(4) = P(4) - 2*P0(2) / 3
It's better to think of this in Fortran terms, as operations on array sections, than as some kind of syntactic sugar for nested loops.

array1(1:A)=array2(1:C,D) Fortran 90 what is the function of the colon

I am not 100% what the role of the 1: is here. At which index to start the copy? But then why not two such parameters for the rank 2 array?
To be a little more explicit:
In Fortran90 and up you access a single array value by giving a single index, and access a subarray (a window of the array) by giving a range of indices separated by a colon.
a(1) = 0.
a(2:5) = (/3.14,2.71,1.62,0./)
You can also give a step size.
a(1:5:2) = (/0,2.71,0./)
And finally, you can leave out values and a default will be inserted. So if a runs from index 1 to 5 then I could write the above as
a(::2) = (/0,2.71,0./)
and the 1 and 5 are implied. Obviously, you shouldn't leave these out if it makes the code unclear.
With a multidimensional array, you can mix and match these on each dimension, as in your example.
You're taking a slice of array2, namely the elements in the D'th column from row 1 to C and putting them in the slice of array1 which is elements 1 through A
So both slices are 1-dimensional arrays
Slice may not be the correct term in Fortran

Non-monolithic arrays in Haskell

I have accepted an answer to the question below, but It seemed I misunderstood how Arrays in haskell worked. I thought they were just beefed up lists. Keep that in mind when reading the question below.
I've found that monolithic arrays in haskell are quite inefficient when using them for larger arrays.
I haven't been able to find a non-monolithic implementation of arrays in haskell. What I need is O(1) time look up on a multidimensional array.
Is there an implementation of of arrays that supports this?
EDIT: I seem to have misunderstood the term monolithic. The problem is that it seems like the arrays in haskell treats an array like a list. I might be wrong though.
EDIT2: Short example of inefficient code:
fibArray n = a where
bnds = (0,n)
a = array bnds [ (i, f i) | i <- range bnds ]
f 0 = 0
f 1 = 1
f i = a!(i-1) + a!(i-2)
this is an array of length n+1 where the i'th field holds the i'th fibonacci number. But since arrays in haskell has O(n) time lookup, it takes O(n²) time to compute.
You're confusing linked lists in Haskell with arrays.
Linked lists are the data types that use the following syntax:
[1,2,3,5]
defined as:
data [a] = [] | a : [a]
These are classical recursive data types, supporting O(n) indexing and O(1) prepend.
If you're looking for multidimensional data with O(1) lookup, instead you should use a true array or matrix data structure. Good candidates are:
Repa - fast, parallel, multidimensional arrays -- (Tutorial)
Vector - An efficient implementation of Int-indexed arrays (both mutable and immutable), with a powerful loop optimisation framework . (Tutorial)
HMatrix - Purely functional interface to basic linear algebra and other numerical computations, internally implemented using GSL, BLAS and LAPACK.
Arrays have O(1) indexing. The problem is that each element is calculated lazily. So this is what happens when you run this in ghci:
*Main> :set +s
*Main> let t = 100000
(0.00 secs, 556576 bytes)
*Main> let a = fibArray t
Loading package array-0.4.0.0 ... linking ... done.
(0.01 secs, 1033640 bytes)
*Main> a!t -- result omitted
(1.51 secs, 570473504 bytes)
*Main> a!t -- result omitted
(0.17 secs, 17954296 bytes)
*Main>
Note that lookup is very fast, after it's already been looked up once. The array function creates an array of pointers to thunks that will eventually be calculated to produce a value. The first time you evaluate a value, you pay this cost. Here are a first few expansions of the thunk for evaluating a!t:
a!t -> a!(t-1)+a!(t-2)-> a!(t-2)+a!(t-3)+a!(t-2) -> a!(t-3)+a!(t-4)+a!(t-3)+a!(t-2)
It's not the cost of the calculations per se that's expensive, rather it's the need to create and traverse this very large thunk.
I tried strictifying the values in the list passed to array, but that seemed to result in an endless loop.
One common way around this is to use a mutable array, such as an STArray. The elements can be updated as they're available during the array creation, and the end result is frozen and returned. In the vector package, the create and constructN functions provide easy ways to do this.
-- constructN :: Unbox a => Int -> (Vector a -> a) -> Vector a
import qualified Data.Vector.Unboxed as V
import Data.Int
fibVec :: Int -> V.Vector Int64
fibVec n = V.constructN (n+1) c
where
c v | V.length v == 0 = 0
c v | V.length v == 1 = 1
c v | V.length v == 2 = 1
c v = let len = V.length v
in v V.! (len-1) + v V.! (len-2)
BUT, the fibVec function only works with unboxed vectors. Regular vectors (and arrays) aren't strict enough, leading back to the same problem you've already found. And unfortunately there isn't an Unboxed instance for Integer, so if you need unbounded integer types (this fibVec has already overflowed in this test) you're stuck with creating a mutable array in IO or ST to enable the necessary strictness.
Referring specifically to your fibArray example, try this and see if it speeds things up a bit:
-- gradually calculate m-th item in steps of k
-- to prevent STACK OVERFLOW , etc
gradualth m k arr
| m <= v = pre `seq` arr!m
where
pre = foldl1 (\a b-> a `seq` arr!b) [u,u+k..m]
(u,v) = bounds arr
For me, for let a=fibArray 50000, gradualth 50000 10 aran at 0.65 run time of just calling a!50000 right away.

Resources