How do I initialize an array of arrays in BCPL? - arrays
I tried let stringArr = newvec(12); and then attempted to initialize each spot in the array as such: let stringArr!i = newvec(5); but that returns an error telling me I cannot do that. Is there anyone here who can help me with this dinosaur language?
You're stretching my memory a bit (to the extent of about three decades) but I seem to recall that let was used only for creating new local variables (also functions and possibly other things, but that's not really relevant for your question).
So the statement let stringArr = newvec(12) is valid in creating the new variable stringArr or, more precisely, a 12-cell anonymous vector and the stringArr variable holding the address of that vector.
However, let stringArr!i = newvec(5) is not valid, because stringArr!i isn't actually a new variable. It's simply the memory contents of cell number i in the already-existing stringArr vector.
In other words, the statement let stringArr = newvec(12) creates both the initial pointer cell and the second layer of pointers, which won't point anywhere useful yet:
+-----------+
| stringArr | ---+
+-----------+ | +-------------+
+--> | stringArr!0 | --> ?
+-------------+
| stringArr!1 | --> ?
+-------------+
: : :
+-------------+
| stringArr!N | --> ?
+-------------+
And, since the pointers already exist, you shouldn't be using let to set them.
It's similar in C in that you wouldn't write:
int xyzzy[10]; // Make array of ten elements.
int xyzzy[0] = 42; // Set first element to something.
since the second line isn't supposed to be defining a new variable, rather it's intent is simply to set one of the existing elements to a given value, done with xyzzy[0] = 42.
Hence the right way to do what you're trying to achieve in BCPL is to avoid using the let keyword for that second class of statements:
let stringArr = newvec(12) // Create new vector AND new variable,
// put vector address into cell for
// that variable.
stringArr!i := newvec(5) // Create new vector, put vector
// address into EXISTING cell.
The solution is sound but both of my versions of BCPL (Martin Richard's and Robert Nordier's obcpl) complain about newvec() and also require := rather than = in the second line. I got it working with:
let stringArr = getvec(12)
stringArr!i := getvec(12)
John Boutland
Related
Move/remove an element in one array into another
I'm doing a project in C involving arrays. What I have is an array of 7 chars, I need to populate an array with 4 random elements from the 7. Then I compare an array I fill myself to it. I don't want to allow repeats. I know how to compare each individual element to another to prevent it but obviously this isn't optimal. So if I remove the elements from the array as I randomly pick them I remove any chance of them being duplicated, or so I think. My question is how would I do this? Example: char name[2+1] = {'a','b'}; char guess[2+1] = {}; so when it randomly picks a or b and puts it in guess[], but the next time it runs it might pick the same. Removing it will get rid of that chance. In bigger arrays it would make it faster then doing all the comparing. Guys it just hit me. Couldn't I switch the element I took with the last element in the array and shrink it by one? Then obviously change the rand() % x modulus by 1 each time?
I can give you steps to do what you intend to do. Code it yourself. Before that let's generalize the problem. You've an array of 'm' elements and you've to fill another 'n' length array by choosing random elements from first array such that there are no repetition of number. Let's assume all numbers are unique in first array. Steps: Keep a pointer or count to track the current position in array. Initialize it to zeroth index initially. Let's call it current. Generate a valid random number within the range of current and 'm'. Let's say its i. Keep generating until you find something in range. Fill second_array with first_array[i]. Swap first_array[i] and first_array[current] and increment current but 1. Repeat through step 2 'n' times. Let's say your array is 2, 3, 7, 5, 8, 12, 4. Its length is 7. You've to fill a 5 length array out of it. Initialize current to zero. Generate random index. Let's say 4. Check if its between current(0) and m(7). It is. Swap first_array[4] and first_array[0]. array becomes 8, 3, 7, 5, 2, 12, 4 Increment current by 1 and repeat.
Here are two possible ways of "removing" items from an array in C (there are other possible way too): Replace the item in the array with another items which states that this item is not valid. For example, if you have the char array +---+---+---+---+---+---+ | F | o | o | b | a | r | +---+---+---+---+---+---+ and you want to "remove" the b the it could look like +---+---+---+------+---+---+ | F | o | o | \xff | a | r | +---+---+---+------+---+---+ Shift the remaining content of the array one step up. To use the same example from above, the array after shifting would look like +---+---+---+---+---+---+ | F | o | o | a | r | | +---+---+---+---+---+---+ This can be implemented by a simple memmove call. The important thing to remember for this is that you need to keep track of the size, and decrease it every time you remove a character. Of course both these methods can be combined: First use number one in a loop, and once done you can permanently remove the unused entries in the array with number two.
To don't forget that an array is just a pointer on the beginning of a set of items of the same type in C. So to remove an element, you simply have to replace the element at the given index with a value that shows that it is not a valid entry i.e. null. As the entry is a simple number, there is no memory management issue (that I know of) but if it were an object, you would have to delete it if it is the last reference you have on it. So let's keep it simple: array2[index2] = array1[index1]; array1[index1] = null; The other way is to change the size of the original array so that it contains one less element, as Joachim stated in his answer.
F# match the beginning of an array
I have a Byte[] buffer that may contain one or multiple data frames, I need to read the first bytes to know how long the actual frame is. This is a "non-working" version of what I want to do: let extractFrame (buffer:byte[]) = match buffer with | [|head1;head2;head3;..|] when head2 < (byte)128 -> processDataFrame buffer head2 | <...others....> | _ -> raise(new System.Exception()) Basically, I need to evaluate the first three bytes, and then call processDataFrame with the buffer and the actual length of the frame. Depending on the headers, the frame can be data, control, etc... Can this be done with any kind of match (lists, sequences, ...etc...)? Or will I have to create another small array with just the length of the header?(I would like to avoid this).
If you want to use matching you could create active pattern (http://msdn.microsoft.com/en-us/library/dd233248.aspx): let (|Head1|_|) (buffer:byte[]) = if(buffer.[0] (* add condition here *)) then Some buffer.[0] else None let (|Head2|_|) (buffer:byte[]) = if(buffer.[1] < (byte)128) then Some buffer.[1] else None let extractFrame (buffer:byte[]) = match buffer with | Head1 h1 -> processDataFrame buffer h1 | Head2 h2 -> processDataFrame buffer h2 ........ | _ -> raise(new System.Exception())
I think that this might actually be easier to do using the plain if construct. But as Petr mentioned, you can use active patterns and define your own patterns that extract specific information from the array. To model what you're doing, I would actually use a parameterized active pattern - you can give it the number of elements from the array that you need and it gives you an array with e.g. 3 elements back: let (|TakeSlice|_|) count (array:_[]) = if array.Length < count then None else Some(array.[0 .. count-1]) let extractFrame (buffer:byte[]) = match buffer with | TakeSlice 3 [|head1;head2;head3|] when head2 < (byte)128 -> processDataFrame buffer head2 | <...others....> | _ -> raise(new System.Exception()) One disadvantage of this approach is that your pattern [|h1; h2; h3|] has to match to the length that you specified 3 - the compiler cannot check this for you.
Row major vs Column Major Matrix Multiplication
I am currently working on a C program trying to compute Matrix Multiplication.. I have approached this task by looping through each column of the second matrix as seen below. I have set size to 1000. for(i=0;i<size;i++) { for(j=0;j<size;j++) { for(k=0;k<size;k++) { matC[i][j]+=matA[i][k]*matB[k][j]; } } } I wanted to know what problematic access pattern is in this implementation.. What makes row/column access more efficient than the other? I am trying to understand this in terms of logic from the use of Caches.. Please help me understand this. Your help is much appreciated :)
If you are talking about use of Caches then you might want to do something called loop tiling. You break the loop into tiles such that inner part of the loop gets stored inside cache (which is quite large these days). So your loop will turn into something like (if you are passing the matrices into a function using pointers ) for(j=0;j<size;j+=t) for(k=0;k<size;k+=t) for(i=0;i<size;i+=t) for(ii=i;ii<MIN(i+t,size);ii++) for(jj=j;jj<MIN(j+t,size);jj++) { var=*(c+ii * size+jj); //Var is a scalar variable for(kk=k;kk<MIN(k+t,size);kk++) { var = var + *(a+ii *size +kk) * *(bt +jj * size+ kk); } *(c+ii *size +jj) = var; } The value of t varies depending on the speedup that you get. It can t = 64,128,256 and so on. There are many other techniques that you can use here. Loop tiling is just once technique to utilize the cache efficiently.Further, you can transpose the B matrix before you send to the multiplication function. That way you will get a linear access of elements of matrix B. To explain you more Consider A -------- and B | | | | -------- | | | | -------- | | | | -------- | | | | Here, you will always consider, to multiply the first row of A with first column of B.And since you are using C I believe, CPU requires extra efforts to read in the all the columns of matrix B one by one inside the memory. To ease up these efforts, you can transpose the matrix and get the rows of matrix B' (which are nothing but columns of B essentially) and use loop tiling to cache the maximum amount of elements for multiplication.Hope this helps.
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.
Initialize Array to Blank custom type OCAML
ive set up a custom data type type vector = {a:float;b:float}; and i want to Initialize an array of type vector but containing nothing, just an empty array of length x. the following let vecarr = Array.create !max_seq_length {a=0.0;b=0.0} makes the array init to {a=0;b=0} , and leaving that as blank gives me errors. Is what im trying to do even possible?
You can not have an uninitialized array in OCaml. But look at it this way: you will never have a hard-to-reproduce bug in your program caused by uninitialized values. If the values you eventually want to place in your array are not available yet, maybe you are creating the array too early? Consider using Array.init to create it at the exact moment the necessary inputs are available, without having to create it earlier and leaving it temporarily uninitialized. The function Array.init takes in argument a function that it uses to compute the initial value of each cell.
How can you have nothing? When you retrieve an element of the newly-initialized array, you must get something, right? What do you expect to get? If you want to be able to express the ability of a value to be either invalid or some value of some type, then you could use the option type, whose values are either None, or Some value: let vecarr : vector option array = Array.create !max_seq_length None match vecarr.(42) with None -> doSomething | Some x -> doSomethingElse
You can initialize and 'a array by using an empty array, i.e., [||]. Executing: let a = [||];; evaluates to: val a : 'a array = [||] which you can then append to. It has length 0, so you can't set anything, but for academic purposes, this can be helpful.