Why not just add one in the secondary hash function after mod? - hash

When working with a hash table with double hashing, the secondary hash function may be something like 7 - (key % 7). It is said that the reason for not using key % 7 directly is to avoid the secondary hash function ever returning 0, such that the algorithm does not keep looping on itself with every step.
Instead of having key % 7:
Key 0: 0 % 7 = 0
Key 1: 1 % 1 = 1
...
Key 6: 6 % 7 = 6
Key 7: 7 % 7 = 0
Key 8: 8 % 7 = 1
...
We have 7 - (key % 7):
Key 0: 7 - (0 % 7) = 7
Key 1: 7 - (1 % 1) = 6
...
Key 6: 7 - (6 % 7) = 1
Key 7: 7 - (7 % 7) = 7
Key 8: 7 - (8 % 7) = 6
...
The sequence changes from a repeating range of 0-6, to a repeating range of 7-1. My question is, would it work similarly well to simply use (key % 7) + 1? It appears to achieve a similar range of repeating 1-7 while avoiding 0s.

Related

Replace values from a certain row onwards column-wise

I have a 10x5 double matrix mat. I also have a 1x5 row vector start_rows. In mat I would like to replace all numbers from specific rows onwards using start_rows. I could use a loop and replace all the numbers column by column. However, I'm sure there is some vectorized solution.
mat = nan(10, 5);
start_rows = [3,5,1,7,2];
% How to avoid that loop
for idx = 1 : numel(start_rows)
mat(start_rows(idx):end, idx) = 1;
end
This can be solved comparing an array of the following form to your start_rows vector:
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
6 6 6 6 6
7 7 7 7 7
8 8 8 8 8
9 9 9 9 9
10 10 10 10 10
which will return a logical array for when the condition is met (this uses broadcasting AKA implicit expansion).
If mat always contains zeros, and you're replacing with ones:
(1:size(mat,1)).'+ mat >= start_rows;
If mat is nonzero:
(1:size(mat,1)).'+ 0*mat >= start_rows; % option 1
(1:size(mat,1)).'+ zeros(size(mat)) >= start_rows; % option 2
If replacing with values other than 1 (or true):
((1:size(mat,1)).'+ 0*mat >= start_rows) * newVal;

Matlab: How to read and extract matrix by specifying header name?

Is it possible to read a matrix under a specified headline from a text file?
I have a text file like this:
Header A (2x3):
3 6 7
5 8 8
Header B (4x4):
23 65 2 6
4 6 7 8
33 7 8 9
so what I want to accomplish is to take the header names as an argument and grab the matrix under it. Is it possible to do in Matlab?
Thanks in advance!!
In addition, try to use this code:
infilename = '1.txt'; % name of your file
m = memmapfile(infilename); % load file to memory (and after close it)
instrings = strsplit(char(m.Data.'),'\n','CollapseDelimiters',true).';
checkstr = 'Header B';
% find all string (their indices) starting with checkstr
ind = find(strncmpi(instrings,checkstr,length(checkstr)));
data = [];
if isempty(ind)
fprintf('\n No strings with %s',checkstr)
else
% first string with string checkstr
n = ind(1)+1;
N = length(instrings);
while n<=N % find all numerical data after string with `checkstr`
convert = str2num(instrings{n});
if isempty(convert), break, end % find non-numerical data
data(end+1,1:length(convert)) = convert; % it because you can have various number of columns
n = n+1;
end
end
data % display load data
output
23 65 2 6 7
4 6 7 8 0
33 7 8 9 0
for the file 1.txt:
Header A (2x3):
3 6 7
5 8 8
Header B (4x4):
23 65 2 6 7
4 6 7 8
33 7 8 9
The following would work, but might not be all that fast if you are dealing with a lot of data:
function [ matrixOut ] = readLineBasedOnHeader( headerString, FileName )
%readLineBasedOnHeader: Scan through a text file, and return matrix below
% a row which starts with the string `headerString`
% Read each row into cell array:
cellStrings = dataread('file', FileName, '%s', 'delimiter', '\n'); %#ok<DDTRD>
% Find the row matching headerString
headerIndex = ismember(cellStrings, headerString);
if sum(headerIndex) == 1
% We've found 1 match; return the matrix
% find how many rows have numberic
rowIdx = find(headerIndex)+1;
matrixOut = str2num(cellStrings{rowIdx}); %#ok<ST2NM>
stillAnumber = ~isempty(matrixOut);
if ~stillAnumber
error('row beneath header found not numeric');
end
while stillAnumber && rowIdx < length(cellStrings)
rowIdx = rowIdx+1;
nextRow = str2num(cellStrings{rowIdx}); %#ok<ST2NM>
stillAnumber = ~isempty(nextRow);
matrixOut = [matrixOut; nextRow]; %#ok<AGROW>
end
elseif sum(headerIndex) > 1
% More than 1 match; throw an error
error('More than 1 copy of header string found');
else % Less than 1 match; throw an error
error('Header string not found');
end
end
Assuming you have a file text_file.txt with the content you have given above, then running:
readLineBasedOnHeader('Header A (2x3):', 'text_file.txt') should return:
ans =
3 6 7
5 8 8
And running:
readLineBasedOnHeader('Header B (4x4):', 'text_file.txt')
Should return:
ans =
23 65 2 6
4 6 7 8
33 7 8 9
Note that this requires you input the full header line (i.e. an exact match for the row); but I'm sure you could have a play with this to get it to match just the Header A bit.

find index of a specific number row wise

Consider the following example
A =
6 9 4 7 10
3 6 5 5 9
10 4 9 8 6
10 6 3 4 6
6 3 3 8 6
6 4 4 4 5
5 10 8 5 7
10 10 8 8 7
5 7 8 9 9
3 3 6 3 9
[~,Inx] =max(A, [],2)
Inx =
5
5
1
1
4
1
2
1
4
5
The above code returns index of the maximum number along each column like in first row the max number is 10 in 5th row so Inx(1) = 5
Can we do the same thing for find ? like for example if I want to find a specific number in each row lets say 8
>> find(A == 8)
ans =
27
28
29
33
35
38
I will get the indices but not row wise like we get for the max() is there some way to do minipulate find to get that ? or else some other way
Update : I know we can use [row,col,v] = find(___) but there is one problem with that it only returns for the rows where the value is present
You can simply convert A to a logical matrix where it's 1 if equal to 8 and 0 otherwise. Then you can use the second output of max to find the column which contains the first 8 in each row. If a row doesn't contain any 8's the first output of max will be a 0 and the second output will be 1.
You can multiply the first and second outputs to zero-out these rows that didn't have an 8.
[has8, col] = max(A == 8, [], 2);
% Zero out any rows that didn't contain an 8
result = has8 .* col;
% 0
% 0
% 4
% 0
% 4
% 0
% 3
% 3
% 3
% 0
If you'd rather have NaN's than 0's, you could do the following which exploits the fact that 0/0 == NaN
result = has8 .* col ./ has8;
% NaN
% NaN
% 4
% NaN
% 4
% NaN
% 3
% 3
% 3
% NaN
Inx = zeros(size(A,1),1); % initialize with default values
[row,col,v] = find(A==8); % find the proper indices
Inx(row) = col; % insert values

i use factor(n) in matlab but it don't work for numbers like ((10^11-1)/11),for same number what can i do?

I use factor(n) in matlab but it don't work for numbers like ((10^11-1)/11) - what can I do? My source is here.
m=input('Enter your number: ');
i=0;
while (i<m)
if(isprime(i))
% sum=factor((10^(i-1)-1));
sum=factor((10^(i-1)-1)/i);
disp(sum);
end
i =i+1;
end
but for large n it returns errors!!
>> FactorGen
Enter your number: 45
3 3
3 3 11
3 3 11 101
3 3 3 7 11 13 37
3 3 11 41 271 9091
3 3 3 7 11 13 37 101 9901
Error using factor (line 26) When n is single or double, its maximum
allowed value is FLINTMAX.
Error in FactorGen (line 7) sum=factor((10^(i-1)-1));
I want the function factor((10^(i-1)-1)) to work for same number. How can I solve my problem?
I think this can be partially alleviated by converting your large number into uint64 format. For R2014b maximum integer that can be handled is:
n = intmax('uint64')
n = 1.8447e+19
While the maximum double that can be handled is:
n = flintmax('double')
n = 9.0072e+15
This can be verified by simple example. Let's use factor on the number larger than flintmax. First, try double:
factor(10^16)
Error using factor (line 26)
When n is single or double, its maximum allowed value is FLINTMAX.
Now, we try uint64:
factor(uint64(10^16))
ans = 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
So, using factor(uint64(x)) increases your limit by several orders. Indeed, there's no sense in using double format for factor function.
By the way, since using factor on large numbers may freeze your system, I suggest using this function:
function f = Factorize(n)
i = 0;
while mod(n,2) == 0
i = i + 1;
n = n/2;
f(i) = 2;
disp([2,n])
end
q = round(sqrt(double(n)));
q = q + 1 - mod(q,2);
for j = 3:2:q
while mod(n,j) == 0
i = i + 1;
f(i) = j;
n = n/j;
end
end
if n > 2;
i = i + 1;
f(i) = n;
end
It is much faster for large numbers and does not overload the system at large n
Hope that helps

MATLAB: Remove duplicate rows with same values in different order

I am trying to find and remove correlated columns from data with the function below
function [ correlated ] = correlated( data, threshold )
% data is m x m matrix
% threshold is correlation threshold
c=corr(data);
[i,j] = find(c>threshold);
A = [i,j];
A=A(find(arrayfun(#(i)length(unique(A(i,:))),1:size(A,1))==size(A,2)),:);
% as A also includes 1 1; 2 2; 3 3; etc so I used above line that I found somewhere
% 6 4
% 8 4
% 4 6
% 8 6
% 4 8
% 6 8
% 14 11
% 11 14
% it should not contain both 6 4; and 4 6; how do I remove all such rows?
end
it should not contain both 6 4; and 4 6; how do I remove all such rows?
uniqueA = unique(sort(A,2), 'rows');