How can I set big array size in pascal? - arrays

I need to create an array in pascal with an enormous size, is such thing possible ?
I know the size number, I mean it's not n or unknown, it's just a really really big number:
2 ^ 255
Can I do that or not ? and if not is there any other way I can make something like that happen ?
Thanks in advance
Update:
The peoblem I'm trying to solve is, by giving a number between 1 to 255 (including 1 & 255), I need to print all Gray Code with length of that number, for example:
giving n=2 the program should print:
00, 01, 11, 10
since I have the max number of size that I can enter I assumed I'd make an array with the max number, the thing is maybe I can solve this with recursion, but I;m very new to pascal so I don't know how can I do that (at least not yet)
here's what I meant:
type arr = array[1..255,1..MAXINT] of integer;
hints and tips can be very helpful <3

I guess it is an XY problem. Is seems useless to store such a big ammount of data in an array instead of fetching it on demand.
Here are the reasons:
The supposed array must be populated programmatically (a human being is unable to populate such an array manually) and this means you definitely have an algorithm for that purpose.
How will you allocate 10^64 GB (calculated by #Alex-K) of memory to store all this data?
Windows 7/8 Ultimate x64 has a maximum RAM limit of 192 GB and 512 GB respectively (for x32 - 4 GB only).
How much time you think it will take to initialize this array and assign values to its memebers?
Conclusion:
Why not to use a function Foo(const bt:byte; const it: cardinal): integer; intended to populate the array for the purpose of fetching the necessary values? You will fetch the data from something like Foo(100 ,32000) instead of MyArray[100, 32000].
If you have some exclusions (values that are different from those calculated by Foo changed at runtime by your user) you can ever store them in an array of TMyRec (or TList) where TMyRec = record Val: integer; Bt: byte; It: cardinal; end;.

I am not proficient in pascal but here is something I have written. It takes a numeric input and converts it in binary then into gray code.
This is the best I could do as again Pascal is not my main lang of work. :)
Uses Math;
var
a,b,d,e,f:integer;
c:array[1..255] of integer;
begin
write('input a decimal number! ');
readln(a);
write('grey code of decimal ',a,' is ');
if a<=1 then write(a) else
repeat
b:=b+1;
d:=a div 2;
c[b]:=a mod 2;
if d<=1 then
begin
b:=b+1;
c[b]:=d;
end;
a:=d;
until d<=1;
for e:=b downto 1 do
begin
//HERE YOU WOULD NEED TO EDIT AND FIX THIS, I THINK THIS WILL ONLY WORK FOR
//1-9
write(c[e -1] xor 1 shl (c[e]>>1));
end;
readln
end.

Related

Convert big number to single digit array

So, I need to convert any number to its reverse and put it in an array.
For example:
123456789 --> [9 8 7 6 5 4 3 2 1]
I managed to do it for small numbers like the example with this:
n=32134654654213
rev=(fliplr(num2str(n)));
mikos=length(rev);
array=[ ]
for i=1:mikos
array=[array,str2num(rev(i))]
end
But when I put a big number like 564465426464334345413435541 the array is always 1x18 double and does not show all the digits.
Any ideas?
edit As you tell me in comments, it is a limit of how many digits a double can hold. You are right, if I use a string input, it works as a charm. Still wondering hot to make it work as a function, with this form :
function digits = GetDigits(n)
As mentioned in the comments, you have a limit on the number of digits a double can store. The limit on a uint64 is bigger (19), but still not sufficient to store your value. I would make sure it does not happen.
function digits = GetDigits(n)
%check if the value behaves as a normal integer
if isnumeric(n)
if n==(n+1),error('n too big, supply as string instead');end
end
rev=(fliplr(num2str(n)));
mikos=length(rev);
array=[ ]
for i=1:mikos
array=[array,str2num(rev(i))]
end
end

Empty find matlab

I am trying to find what's the number on the array for the 1000 value. This is my code:
size = linspace(420, 2200, 100000);
size1000 = find(size==1000);
It returns an empty variable for size 1000. If I actually change 1000 with 420 it actually returns 1 like it should. Why is this not working?
The result of find is empty because 1000 is not in the array and isn't expected to be. Using the inputs to linspace, your expected step size is going to be 0.0178
(2200 - 420) / 100000
% 0.0178
With this step size and a starting value of 420, you're never going to hit the value 1000 exactly. The closest values in the array are 1000.001 and 999.983. If you want to identify values that are close to 1000, you can do something like the following instead.
inds = find(abs(size - 1000) < 0.01);
As a side-note, do not use size as the name of a variable since that is the name of a built-in MATLAB function and using it as a variable name can result in unexpected behavior.
You can also use logical indexing to simply remove all of the values below 1000, and then you know that the first component of what is left will be your answer....
a = size(size>1000);
a(1)
For what it is worth, please PLEASE do not use size as a variable name. size is an important MATLAB function to get the size of a matrix. For example,
>> size(randn(2,3))
ans =
2 3
However, when you declare a variable named size, like you do in your code, you will hide this function. So now, at some point later in your code, if you called size(randn(2,3)), you will get the cryptic error
Subscript indices must either be real positive integers or
logicals.
These are extremely tricky to track down, so please avoid it.

Operating elementwise on an array

I'm trying to check if my arrays are returning nonsense by accessing out of bounds elements, in fortran. And I want to check these values are less than one, and if they are, change them to one.
This is the piece of my code causing issues:
lastNeighLabel=(/clusterLabel(jj-1,kk,ll), clusterLabel(jj,kk-1,ll), clusterLabel(jj,kk,ll-1)/)
LastNeighLabel contains the cluster label (between 1 and n, where n isthe total number of unique seperate clusters found) for the last neighbour in the x,y,z direction respectively.
When jj or kk or ll are 1, they try and access the 0th element in the array, and as FORTRAN counts from 1 in arrays, it tries to destroy the universe. I'm currently in a tangled mess of about 8 if/elseif statements trying to code for every eventuality. But I was hoping there was a way of operating on each element. So basically I'd like to say where((/jj-1,kk-1,ll-1/).lt.1) do clusterLabel(jj-1,kk,ll)=0 etc depending on which element is causing the problem.
But I can't think of a way to do that because where will only manipulate the variables passed to it, not a different array at the same index. Or am I wrong?
Will gladly edit if this doesn't make sense.
It is not obligatory that Fortran accesses arrays starting from one. Any starting value is allowed. If it more convenient to you to have a zero indexed array, declare the array as:
real, dimension (0:N-1, 0:M-1) :: array
Or
real, dimension (0:N, 0:M) :: array
and have the 0 indices be extra to catch special cases.
This might be another solution to your problem, since zero index values would be legal.
Another possible way to approach this, is to create an extended cluster label array (with index bounds starting at 0), which is equal to the cluster label array with a layer of zeroes tacked on the outside. You can then let your loop run safely over all values of jj, kk, and ll. It depends on the size of the array if this is a feasible solution.
integer :: extended_cluster_label(0:size(cluster_label,1), &
0:size(cluster_label,2), &
0:size(cluster_label,3) &
)
extended_cluster_label(0,:,:) = 0
extended_cluster_label(:,0,:) = 0
extended_cluster_label(:,:,0) = 0
extended_cluster_label(1:, 1:, 1:) = cluster_label
Maybe you could use a function?
real function f(A,i,j,k)
real :: A(:,:,:)
integer :: i,j,k
if (i==0.or.j==0.or.k==0) then
f=0
else
f=A(i,j,k)
endif
end function f
and then use f(clusterLabel,jj-1,kk,ll) etc.

Optimization using look up table

I have made some c code for a program, which does some psycho-acoustics on sound data.
There is a piece of code which runs very slowly.
I think it would be best to use a look up table. How would one go about implementing it?
Any pointers or help would be appreciated! :)
Your values are not equidistant so it is not that easy. But its still possible: take your greatest common divisor of all your condition-values (thats here 50) and then make your table
byteout = lut[difference/50 + 12];
And in the lookup table you can just use your values in the posted order, where you duplicate the entries in case your stepping is 100.
Btw it just see, there is a mistake, all your negative cases are catched by your first <=0 (my example assumes that you want to omit the first case).
Firstly, take a look at where you want that first check against 0, as it makes all of your negative checks pointless.
Secondly, I would probably construct a lookup table as an array of 1300 elements, offset by 500 (your lowest negative value). Each element would be the result you want when you look up that number. If you are looking for something less than -500, don't check the array.
So it would look something like this:
table[0] = 0b0110; // -500 through -599
table[1] = 0b0110;
...
table[100] = 0b0101; // -400 through -499
table[101] = 0b0101;
...
Lookup would be:
if (value <= -600) {
return 0b0111;
}
else {
return table[value + 600];
}
It's a small enough number of values that the size of the array is not prohibitive. Initialize with a loop at the beginning of your program.
Binary search for the win.
Store all possible values in an array, and be sure to sort them.
Start in the middle and see if difference is less than that value. If so, move to the middle of what's left of your cursor and try again. If not, move to the right. Keep going until you find the value you want, and then use that.
Your array could be of structs that have the minimum value and the corresponding byteout value.
EDIT: To clear up possible misunderstandings, with "every possible value" I don't mean every number between -1400 and 1400, just values you check against in your original code.
Let's look at the first bit:
if (difference <= 0)
byteout = 0b0000;
else if (difference <= -600)
byteout = 0b0111;
Let's say you have a value of -601.
Is it <= 0? Yes, so byteout = 0b0000;
you never get to the -600. So effectively, ALL negative values are 0b0000. This may or may not be by design, but if it is you can get rid of all other negative values.
Otherwise, I would consider reducing this to a formula (with as few branches as possible) or going with #Ebomike's solution of a precomputed lookup table and binary search.

Finding whether a value is equal to the value of any array element in MATLAB

Can anyone tell me if there is a way (in MATLAB) to check whether a certain value is equal to any of the values stored within another array?
The way I intend to use it is to check whether an element index in one matrix is equal to the values stored in another array (where the stored values are the indices of the elements which meet a certain criteria).
So, if the indices of the elements which meet the criteria are stored in the matrix below:
criteriacheck = [3 5 6 8 20];
Going through the main array (called array) and checking if the index matches:
for i = 1:numel(array)
if i == 'Any value stored in criteriacheck'
%# "Do this"
end
end
Does anyone have an idea of how I might go about this?
The excellent answer previously given by #woodchips applies here as well:
Many ways to do this. ismember is the first that comes to mind, since it is a set membership action you wish to take. Thus
X = primes(20);
ismember([15 17],X)
ans =
0 1
Since 15 is not prime, but 17 is, ismember has done its job well here.
Of course, find (or any) will also work. But these are not vectorized in the sense that ismember was. We can test to see if 15 is in the set represented by X, but to test both of those numbers will take a loop, or successive tests.
~isempty(find(X == 15))
~isempty(find(X == 17))
or,
any(X == 15)
any(X == 17)
Finally, I would point out that tests for exact values are dangerous if the numbers may be true floats. Tests against integer values as I have shown are easy. But tests against floating point numbers should usually employ a tolerance.
tol = 10*eps;
any(abs(X - 3.1415926535897932384) <= tol)
you could use the find command
if (~isempty(find(criteriacheck == i)))
% do something
end
Note: Although this answer doesn't address the question in the title, it does address a more fundamental issue with how you are designing your for loop (the solution of which negates having to do what you are asking in the title). ;)
Based on the for loop you've written, your array criteriacheck appears to be a set of indices into array, and for each of these indexed elements you want to do some computation. If this is so, here's an alternative way for you to design your for loop:
for i = criteriacheck
%# Do something with array(i)
end
This will loop over all the values in criteriacheck, setting i to each subsequent value (i.e. 3, 5, 6, 8, and 20 in your example). This is more compact and efficient than looping over each element of array and checking if the index is in criteriacheck.
NOTE: As Jonas points out, you want to make sure criteriacheck is a row vector for the for loop to function properly. You can form any matrix into a row vector by following it with the (:)' syntax, which reshapes it into a column vector and then transposes it into a row vector:
for i = criteriacheck(:)'
...
The original question "Can anyone tell me if there is a way (in MATLAB) to check whether a certain value is equal to any of the values stored within another array?" can be solved without any loop.
Just use the setdiff function.
I think the INTERSECT function is what you are looking for.
C = intersect(A,B) returns the values common to both A and B. The
values of C are in sorted order.
http://www.mathworks.de/de/help/matlab/ref/intersect.html
The question if i == 'Any value stored in criteriacheck can also be answered this way if you consider i a trivial matrix. However, you are proably better off with any(i==criteriacheck)

Resources