Julia: 2d array assignment - arrays

I'm trying to do the assignment in the 2d array with the nested loop. I'm trying to access the elements of the array as follows. But I get a mistake. I've searched, but I didn't get results. How can I assign Julia in the 2d array?
for x in 1:total
for y in 1:W
#show (x, y)
if agirliklar[x] <= y
V[x][y] = getMax(V[x-1][y], degerler[x] + V[x-1][y - agirliklar[x]])
else
print("sa")
V[x][y] = V[x-1][y]
end
end
end
BoundsError: attempt to access 7×6 Array{Int64,2} at index [0]
My code
Error

In Julia arrays are 1-based not 0-based.
You try to access V[x-1] where x can take value of 1.
Site note: always provide a minimum working example (MWE) rather than just dumping a part of your production code.

(At least) two things are wrong here:
As #PrzemyslawSzufel says, ordinary Julia arrays are 1-indexed, so you cannot access them at index zero. Though it is possible to get special arrays that are 0-indexed.
If V is a 2D array, as you are saying, you cannot access it like this: V[x][y]. Instead you access them like this: V[x, y]. You can read more about this here: https://docs.julialang.org/en/v1/manual/arrays/#man-array-indexing-1

Related

Delphi array conversions between 2D and 1D and back again

I am doing some work with OpenCL for GPU processing of calculations. OpenCL cannot accept a 2D array passed to it, so my 2D arrays need to be converted to 1D and then back to 2D after processing them.
For 2D to 1D I use code like...
i:=0;
for y:=0 to yDim-1 do
begin
for x:=0 to xDim-1 do
begin
FlatArray1[i]:=Array1[x,y];
FlatArray2[i]:=Array2[x,y];
FlatArray3[i]:=Array3[x,y];
FlatArray4[i]:=Array4[x,y];
FlatArray5[i]:=Array5[x,y];
inc(i);
end;
end;
I can then pass these 1D arrays as parameters to OpenCL. The OpenCL processing time is very fast. Once OpenCL is done the 1D arrays need to be converted back into 2D.
x:=0;
y:=0;
for loop:=0 to 1DArraySize-1 do
begin
Array1[x,y]:=FlatArray1[loop];
Array2[x,y]:=FlatArray2[loop];
Array3[x,y]:=FlatArray3[loop];
Array4[x,y]:=FlatArray4[loop];
Array5[x,y]:=FlatArray5[loop];
inc(x);
if x=xDim then
begin
x:=0;
inc(y);
end;
end;
An example of time ratio is 60 ms for the OpenCL calculations that process the arrays and 550 ms for the array conversion loops.
The 550ms is longer than using CPU alone for calculations so it is killing the advantage OpenCL gives for calculation times.
Are there any clever tricks for more efficiently converting the arrays from 2D to 1D and back again?
Thanks for any ideas.
The fastest conversion is avoiding conversion at all.
You can have one data copy in memory and cast it to one-dimensional or 2D array. But note the x should be the second dimension for consistent data layout. It is not possible if 2D array is dynamic (it does not occupy single memory region).
Simple example without thorough type checking (perhaps OpenCL function needs just address of data):
procedure XX(p:PByteArray);
begin
Inc(p[47]);
end;
type
TArr2D = array[0..5, 0..7] of Byte;
PArr2D = ^TArr2D;
TArr1D = array[0..47] of Byte;
var
A: TArr2D;
begin
A[5,7] := 57;
XX(#A);
Caption := A[5,7].ToString;
Also it is possible to use absolute directive to share the same data, and records with variants where two fields share the same memory too.
procedure YY(var B: TArr1D);
begin
Dec(B[47]);
end;
var
A: TArr2D;
AA: TArr1D absolute A;
begin
A[5,7] := 57;
YY(AA);
Caption := A[5,7].ToString;
Some say that because in Delphi dynamic 2D arrays are declared as array of array of [some type] this is a weakness of language which makes working with them much harder in compared to other programming languages.
Well I disagree. Granted it does require a bit different thinking. In the end this can even be an advantage that is if you do know how to use it. How?
Well when you declare array as array of array of [some type] the outer dimension of this 2D array is actually array of references to 1D array that represent inner dimension of the said 2D array. We can use this to our advantage since we can assign any such reference from the outer dimension of our 2D array to another variable of the same type of inner arrays.
So if you declare your 2D array like:
type
//1D array that will prepresent inner dimension of 2D array
T1DArr = array of Integer;
//1D array that stores references to 1D arrays of inner dimension
//which in fact turns this into 2D array.
T2Darr = array of T1DArr;
you can then work with 2D array in a way you area already familiar with
var
A1DArr: T1DArr; //Declare variable for 1D array
A2Darr: T2DArr; //Declare variable for 2D array
begin
//Set dimension of 2D array
SetLength(A2DArr,10,10);
//Set value to specific item of the 2D array
A2DArr[X,Y] := 15;
But you can then assign reference of any of the inner dimension arrays to separate variable using:
//Assign reference to inner array with index of 1 to 1D array variable
A1DArr := A2DArr[1];
EDIT: But how does this help you in converting your 2D array into one 1D array.
As part of built in functionality to work with arrays Delphi includes ability to easily join multiple dynamic arrays into one. So no need to move data from 2D array into 1D array by accessing each array item individually inside a nested loop.
You can use system System.Concat procedure to join two dynamic arrays together.
Or you can just use add operator like so
A1Darr := A2DArr[0] + A2DArr[1];
This joins inner arrays of 2D array with index 0 and 1 into one 1D array
PS: Another thing that you should change in your code is to work one one array at time. In your code you have nested loop inside which you are working on five different arrays. It would be better to have five separate nested loops one for each array. Why?
When you access first item of an array part of that array is pushed on a stack. But when you access the second item of that array part of the data from that array is already present on stack so access is much faster.
Now this won't work if you are often jumping between different arrays and you would end up pushing data on stack much more often which can in the end hurt performance as it negates purpose of stack.

How to convert vectors to arrays in ECLiPSe (CLP)? (or Prolog)

I have to solve Sudoku puzzles in the format of a vector containing 9 vectors (of length 9 each). Seeing as vectors are linked lists in Prolog, I figured the search would go faster if I transformed the puzzles in a 2D array format first.
Example puzzle:
puzzle(P) :- P =
[[_,_,8,7,_,_,_,_,6],
[4,_,_,_,_,9,_,_,_],
[_,_,_,5,4,6,9,_,_],
[_,_,_,_,_,3,_,5,_],
[_,_,3,_,_,7,6,_,_],
[_,_,_,_,_,_,_,8,9],
[_,7,_,4,_,2,_,_,5],
[8,_,_,9,_,5,_,2,3],
[2,_,9,3,_,8,7,6,_]].
I'm using ECLiPSe CLP to implement a solver. The best I've come up with so far is to write a domain like this:
domain(P):-
dim(P,[9,9]),
P[1..9,1..9] :: 1..9.
and a converter for the puzzle (parameter P is the given puzzle and Sudoku is the new defined grid with the 2D array). But I'm having trouble linking the values from the given initial puzzle to my 2D array.
convertVectorsToArray(Sudoku,P):-
( for(I,1,9),
param(Sudoku,P)
do
( for(J,1,9),
param(Sudoku,P,I)
do
Sudoku[I,J] is P[I,J]
)
).
Before this, I tried using array_list (http://eclipseclp.org/doc/bips/kernel/termmanip/array_list-2.html), but I kept getting type errors. How I did it before:
convertVectorsToArray(Sudoku,P):-
( for(I,1,9),
param(Sudoku,P)
do
( for(J,1,9),
param(Sudoku,P,I)
do
A is Sudoku[I],
array_list(A,P[I])
)
).
When my Sudoku finally outputs the example puzzle P in the following format:
Sudoku = []([](_Var1, _Var2, 8, 7, ..., 6), [](4, ...), ...)
then I'll be happy.
update
I tried again with the array_list; it almost works with the following code:
convertVectorsToArray(Sudoku,P):-
( for(I,1,9),
param(Sudoku,P)
do
X is Sudoku[I],
Y is P[I],
write(I),nl,
write(X),nl,
write(Y),nl,
array_list(X, Y)
).
The writes are there to see how the vectors/arrays look like. For some reason, it stops at the second iteration (instead of 9 times) and outputs the rest of the example puzzle as a vector of vectors. Only the first vector gets assigned correctly.
update2
While I'm sure the answer given by jschimpf is correct, I also figured out my own implementation:
convertVectorsToArray(Sudoku,[],_).
convertVectorsToArray(Sudoku,[Y|Rest],Count):-
X is Sudoku[Count],
array_list(X, Y),
NewCount is Count + 1,
convertVectorsToArray(Sudoku,Rest,NewCount).
Thanks for the added explanation on why it didn't work before though!
The easiest solution is to avoid the conversion altogether by writing your puzzle specification directly as a 2-D array. An ECLiPSe "array" is simply a structure with the functor '[]'/N, so you can write:
puzzle(P) :- P = [](
[](_,_,8,7,_,_,_,_,6),
[](4,_,_,_,_,9,_,_,_),
[](_,_,_,5,4,6,9,_,_),
[](_,_,_,_,_,3,_,5,_),
[](_,_,3,_,_,7,6,_,_),
[](_,_,_,_,_,_,_,8,9),
[](_,7,_,4,_,2,_,_,5),
[](8,_,_,9,_,5,_,2,3),
[](2,_,9,3,_,8,7,6,_)).
You can then use this 2-D array directly as the container for your domain variables:
sudoku(P) :-
puzzle(P),
P[1..9,1..9] :: 1..9,
...
However, if you want to keep your list-of-lists puzzle specification, and convert that to an array-of-arrays format, you can use array_list/2. But since that only works for 1-D arrays, you have to convert the nesting levels individually:
listoflists_to_matrix(Xss, Xzz) :-
% list of lists to list of arrays
( foreach(Xs,Xss), foreach(Xz,Xzs) do
array_list(Xz, Xs)
),
% list of arrays to array of arrays
array_list(Xzz, Xzs).
As for the reason your own code didn't work: this is due to the subscript notation P[I]. This
requires P to be an array (you were using it on lists)
works only in contexts where an arithmetic expression is expected, e.g. the right hand side of is/2, in arithmetic constraints, etc.

Arrays in matlab

I have a structure names eye_record which has 6 fields, one of which is x_pos_measured_deg:[1800x1 double]
I want to declare an array in such a way that using for loop, i can get all values of that specific field into a new array and do some work on them. Can anyone show me how to do that? here is m code:
arr=zeros(1,1800);
for t=1:length(eye_record);
arr(t)= eye_record(t).x_pos_measured_deg;
end
it gives me this error: In an assignment A(I) = B, the number of elements in B and I must be the same. How can i fix this? or how should i declare my array so that it won't give me this error? I want all the objects or values, which are in x_pos_measured_deg field to go into my new array.
Your eye_record is struct, not array, so you can not use indexing with eye_record. Your eye_record.x_pos_measured_deg is array and you have to loop through it. So the loop should be:
arr=zeros(1,1800);
for t=1:length(eye_record.x_pos_measured_deg)
arr(t)= eye_record.x_pos_measured_deg(t);
end
But actually, you can assign values directly like:
arr=zeros(1,1800);
arr = eye_record.x_pos_measured_deg';
since you declared arr to have size of 1x1800, and eye_record.x_pos_measured_deg has size of 1800x1.
Without arr=zeros(1,1800);, then no ' at the end:
arr = eye_record.x_pos_measured_deg;

R populate multidimensional array

Hi I am stuck with one of these simple but time-consuming errors:
How can I populate an array with loops? I know I am on a C approach here
and R isn't C.
Data <-[SOMETHING HERE]
One <-200
Two <-100
array222 <- array(0,length(SomeLength))
for (i in 1:One)
{
for (j in 1:Two)
{
array222[i][j] = sample(Data,1)
}
I want to populate the array with random samples from another dataset but all
I get is this:
Warning in array222[i][j] = sample(Data, 1) :
number of items to replace is not a multiple of replacement length
First of all, you wouldn't use loops to do this in R. You'd just do
array222 <- matrix(sample(Data, One*Two, replace=T), nrow=One, ncol=Two)
But going back to your code, you fail to properly initialize your array222 variable. The matrix() syntax is probably easier for a 2-D array, but you could also use array(0, dim=c(One,Two)). You need to create it with the proper dimensions.
And additionally, the proper way to index a dimensional array is
array222[i,j] #NOT array222[i][j]

2d array in Haskell

I'm learning how to use arrays in Haskell, for example, generating a times table:
Prelude Data.Array> array ((0,0),(10,12)) [((x,y),x*y) | x<-[0..10], y<-[0..12]]
array ((0,0),(10,12)) [((0,0),0),((0,1),0),((0,2),0),((0,3),0),((0,4),0),((0,5),0),((0,6),0),((0,7),0),((0,8),0),((0,9),0),((0,10),0),((0,11),0),((0,12),0),((1,0),0),((1,1),1),((1,2),2),((1,3),3),((1,4),4),((1,5),5),((1,6),6),((1,7),7),((1,8),8),((1,9),9),((1,10),10),((1,11),11),((1,12),12),((2,0),0),((2,1),2),((2,2),4),((2,3),6),((2,4),8),((2,5),10),((2,6),12),((2,7),14),((2,8),16),((2,9),18),((2,10),20),((2,11),22),((2,12),24),((3,0),0),((3,1),3),((3,2),6),((3,3),9),((3,4),12),((3,5),15),((3,6),18),((3,7),21),((3,8),24),((3,9),27),((3,10),30),((3,11),33),((3,12),36),((4,0),0),((4,1),4),((4,2),8),((4,3),12),((4,4),16),((4,5),20),((4,6),24),((4,7),28),((4,8),32),((4,9),36),((4,10),40),((4,11),44),((4,12),48),((5,0),0),((5,1),5),((5,2),10),((5,3),15),((5,4),20),((5,5),25),((5,6),30),((5,7),35),((5,8),40),((5,9),45),((5,10),50),((5,11),55),((5,12),60),((6,0),0),((6,1),6),((6,2),12),((6,3),18),((6,4),24),((6,5),30),((6,6),36),((6,7),42),((6,8),48),((6,9),54),((6,10),60),((6,11),66),((6,12),72),((7,0),0),((7,1),7),((7,2),14),((7,3),21),((7,4),28),((7,5),35),((7,6),42),((7,7),49),((7,8),56),((7,9),63),((7,10),70),((7,11),77),((7,12),84),((8,0),0),((8,1),8),((8,2),16),((8,3),24),((8,4),32),((8,5),40),((8,6),48),((8,7),56),((8,8),64),((8,9),72),((8,10),80),((8,11),88),((8,12),96),((9,0),0),((9,1),9),((9,2),18),((9,3),27),((9,4),36),((9,5),45),((9,6),54),((9,7),63),((9,8),72),((9,9),81),((9,10),90),((9,11),99),((9,12),108),((10,0),0),((10,1),10),((10,2),20),((10,3),30),((10,4),40),((10,5),50),((10,6),60),((10,7),70),((10,8),80),((10,9),90),((10,10),100),((10,11),110),((10,12),120)]
I'm wondering if this is the correct way to hold a matrix or 2d-array of values? Why does it give a list of ((x,y),value) instead of giving a table of values? Is there a way to change how it prints the array?
Using a tuple as the index is the correct way of getting a multidimensional array. If you want to print it out differently, you'll have to write your own function to convert it to a string.
For example, you could have something like this:
showTable arr =
unlines $ map (unwords . map (show . (arr !))) indices
where indices = [[(x, y) | x <- [startX..endX]] | y <- [startY..endY]]
((startX, startY), (endX, endY)) = bounds arr
That's just the Show instance. The Array constructor is not exported from Data.Array, so you can't directly construct an array. The Show instance produces valid Haskell code that can be used to construct the array from the list of its associations.

Resources