I am applying transformations on a column by column basis to a matrix, the problem is that this transformation will not affect each column equally, leaving me with a collection of different length columns. I want to further iterate over these columns but cannot find the way to word it in Octave.
for v = 1:6
gate_values( 1, (2*v) ) = C(1, v);
gate_values( 1, (2*v)-1 ) = t(1);
for i = 1 : (length(C) - 1)
if C( i+1, v ) - C(i, v) > 0.05 % Taken as 10% of bin value
gate_values( i+1, (2*v) ) = C( i+1,v );
gate_values( i+1, (2*v)-1 ) = t( i+1 );
endif
endfor
t_imp = toc
endfor
gate_values_1(:,1)= nonzeros( gate_values(:, 1) );
gate_values_1(:,2)= nonzeros( gate_values(:, 2) );
gate_values_2(:,1)= nonzeros( gate_values(:, 3) );
gate_values_2(:,2)= nonzeros( gate_values(:, 4) );
gate_values_3(:,1)= nonzeros( gate_values(:, 5) );
gate_values_3(:,2)= nonzeros( gate_values(:, 6) );
gate_values_4(:,1)= nonzeros( gate_values(:, 7) );
gate_values_4(:,2)= nonzeros( gate_values(:, 8) );
gate_values_5(:,1)= nonzeros( gate_values(:, 9) );
gate_values_5(:,2)= nonzeros( gate_values(:,10) );
gate_values_6(:,1)= nonzeros( gate_values(:,11) );
gate_values_6(:,2)= nonzeros( gate_values(:,12) );
The nonzeros function means the columns will be different lengths so i cannot simply populate a matrix this way, would there be a way to create these gate_value columns by iterating for example I have tried (among variations).
for k=1:6
gate_values_k(:,1) = nonzeros( gate_values(:,1) );
but this causes an error (for reference I'm assuming this is possible as in vba i could write gate_values_ & k to achieve this). Thanks.
Numerical arrays generally do not allow you to have columns of different lengths. Obviously if your columnwise operations involve a "zero element" with regard to that operation, you could simply pad your columns with that zero element.
Otherwise, you are probably looking for 'cell arrays' instead. Presumably you can create a cell array where each cell contains a vector (of non-equal length to all others), and then use something like arrayfun, cellfun, accumdim / accumarray etc (depending on the exact operation you're trying to perform) to perform aggregate operations across the cells.
Related
I want to test the hypothesis whether some 30 occurrences should fit a Poisson distribution.
#GNU Octave
X = [8 0 0 1 3 4 0 2 12 5 1 8 0 2 0 1 9 3 4 5 3 3 4 7 4 0 1 2 1 2]; #30 observations
bins = {0, 1, [2:3], [4:5], [6:20]}; #each bin can be single value or multiple values
I am trying to use Pearson's chi-square statistics here and coded the below function. I want a Poisson vector to contain corresponding Poisson probabilities for each bin and count the observations for each bin. I feel the loop is rather redundant and ugly. Can you please let me know how can I re-factor the function without the loop and make the whole calculation cleaner and more vectorized?
function result= poissonGoodnessOfFit(bins, observed)
assert(iscell(bins), "bins should be a cell array");
assert(all(cellfun("ismatrix", bins)) == 1, "bin entries either scalars or matrices");
assert(ismatrix(observed) && rows(observed) == 1, "observed data should be a 1xn matrix");
lambda_head = mean(observed); #poisson lambda parameter estimate
k = length(bins); #number of bin groups
n = length(observed); #number of observations
poisson_probability = []; #variable for poisson probability for each bin
observations = []; #variable for observation counts for each bin
for i=1:k
if isscalar(bins{1,i}) #this bin contains a single value
poisson_probability(1,i) = poisspdf(bins{1, i}, lambda_head);
observations(1, i) = histc(observed, bins{1, i});
else #this bin contains a range of values
inner_bins = bins{1, i}; #retrieve the range
inner_bins_k = length(inner_bins); #number of values inside
inner_poisson_probability = []; #variable to store individual probability of each value inside this bin
inner_observations = []; #variable to store observation counts of each value inside this bin
for j=1:inner_bins_k
inner_poisson_probability(1,j) = poisspdf(inner_bins(1, j), lambda_head);
inner_observations(1, j) = histc(observed, inner_bins(1, j));
endfor
poisson_probability(1, i) = sum(inner_poisson_probability, 2); #assign over the sum of all inner probabilities
observations(1, i) = sum(inner_observations, 2); #assign over the sum of all inner observation counts
endif
endfor
expected = n .* poisson_probability; #expected observations if indeed poisson using lambda_head
chisq = sum((observations - expected).^2 ./ expected, 2); #Pearson Chi-Square statistics
pvalue = 1 - chi2cdf(chisq, k-1-1);
result = struct("actual", observations, "expected", expected, "chi2", chisq, "pvalue", pvalue);
return;
endfunction
There's a couple of things worth noting in the code.
First, the 'scalar' case in your if block is actually identical to your 'range' case, since a scalar is simply a range of 1 element. So no special treatment is needed for it.
Second, you don't need to create such explicit subranges, your bin groups seem to be amenable to being used as indices into a larger result (as long as you add 1 to convert from 0-indexed to 1-indexed indices).
Therefore my approach would be to calculate the expected and observed numbers over the entire domain of interest (as inferred from your bin groups), and then use the bin groups themselves as 1-indices to obtain the desired subgroups, summing accordingly.
Here's an example code, written in the octave/matlab compatible subset of both languges:
function Result = poissonGoodnessOfFit( BinGroups, Observations )
% POISSONGOODNESSOFFIT( BinGroups, Observations) calculates the [... etc, etc.]
pkg load statistics; % only needed in octave; for matlab buy statistics toolbox.
assert( iscell( BinGroups ), 'Bins should be a cell array' );
assert( all( cellfun( #ismatrix, BinGroups ) ) == 1, 'Bin entries either scalars or matrices' );
assert( ismatrix( Observations ) && rows( Observations ) == 1, 'Observed data should be a 1xn matrix' );
% Define helpful variables
RangeMin = min( cellfun( #min, BinGroups ) );
RangeMax = max( cellfun( #max, BinGroups ) );
Domain = RangeMin : RangeMax;
LambdaEstimate = mean( Observations );
NBinGroups = length( BinGroups );
NObservations = length( Observations );
% Get expected and observed numbers per 'bin' (i.e. discrete value) over the *entire* domain.
Expected_Domain = NObservations * poisspdf( Domain, LambdaEstimate );
Observed_Domain = histc( Observations, Domain );
% Apply BinGroup values as indices
Expected_byBinGroup = cellfun( #(c) sum( Expected_Domain(c+1) ), BinGroups );
Observed_byBinGroup = cellfun( #(c) sum( Observed_Domain(c+1) ), BinGroups );
% Perform a Chi-Square test on the Bin-wise Expected and Observed outputs
O = Observed_byBinGroup; E = Expected_byBinGroup ; df = NBinGroups - 1 - 1;
ChiSquareTestStatistic = sum( (O - E) .^ 2 ./ E );
PValue = 1 - chi2cdf( ChiSquareTestStatistic, df );
Result = struct( 'actual', O, 'expected', E, 'chi2', ChiSquareTestStatistic, 'pvalue', PValue );
end
Running with your example gives:
X = [8 0 0 1 3 4 0 2 12 5 1 8 0 2 0 1 9 3 4 5 3 3 4 7 4 0 1 2 1 2]; % 30 observations
bins = {0, 1, [2:3], [4:5], [6:20]}; % each bin can be single value or multiple values
Result = poissonGoodnessOfFit( bins, X )
% Result =
% scalar structure containing the fields:
% actual = 6 5 8 6 5
% expected = 1.2643 4.0037 13.0304 8.6522 3.0493
% chi2 = 21.989
% pvalue = 0.000065574
A general comment about the code; it is always preferable to write self-explainable code, rather than code that does not make sense by itself in the absence of a comment. Comments generally should only be used to explain the 'why', rather than the 'how'.
I have tried to generalise my tic-tac-toe game for an NxN grid. I have everything working but am finding it hard to get the code needed to detect a win.
This is my function at the moment where I loop over the rows and columns of the board. I can't figure out why it's not working currently. Thanks
def check_win(array_board):
global winner
for row in range(N):
for i in range(N-1):
if array_board[row][i] != array_board[row][i+1] or array_board[row][i] == 0:
break
if i == N-1:
winner = array_board[row][0]
pygame.draw.line(board, (0, 0, 0), (75, (row * round(height / N) + 150)), (825, (row * round(height / N) + 150)), 3)
for col in range(N):
for j in range(N-1):
if array_board[j][col] == 0 or array_board[col][j] != array_board[col][i+1]:
break
if j == N - 1:
winner = array_board[0][col]
pygame.draw.line(board, (0, 0, 0), (col * round(width / N) + 150, 75), (col * round(width / N) + 150, 825), 3)
You don't specify in your question, so my noughts-and-crosses grid is a 2D array of characters, with some default "empty" string (a single space).
def getEmptyBoard( size, default=' ' ):
""" Create a 2D array <size> by <size> of empty string """
grid = []
for j in range( size ):
row = []
for i in range( size ): # makes a full empty row
row.append( default )
grid.append( row )
return ( size, grid )
So given a 2D grid of strings, how does one check for a noughts-and-crosses Win? This would be when the count of the same character in a particular row or column is equal to the size of the grid.
Thus if you have a 5x5 grid, any row with 5 of the same item (say 'x') is a winner. Similarly for a column... 5 lots of 'o' is a win.
So given a 2D array, how do you check for these conditions. One way to do this is to tally the number of occurrences of separate symbols in each cell. If that tally reaches the 5 (grid size), then whatever that symbol is, it's a winner.
def checkForWin( board, default=' ' ):
winner = None
size = board[0]
grid = board[1]
### Tally the row and column
for j in range( size ):
col_results = {}
### Count the symbols in this column
for i in range( size ):
value = grid[i][j]
if ( value in col_results.keys() ):
col_results[ value ] += 1
else:
col_results[ value ] = 1
### Check the tally for a winning count
for k in col_results.keys():
if ( k != default and col_results[k] >= size ):
winner = k # Found a win
print("Winner: column %d" % ( j ) )
break
if ( winner != None ):
break
# TODO: also implement for rows
# TODO: also implement for diagonals
return winner # returns None, or 'o', 'x' (or whatever used for symbols)
The above function uses two loops and a python dictionary to keep a list of what's been found. It's possible to check both the row and columns in the same loops, so it's not really row-by-row or column-by-column, just two loops of size.
Anyway, so during the loop when we first encounter an x, it will be added to the dictionary, with a value of 1. The next time we find an x, the dictionary is used to tally that occurrence, dict['x'] → 2, and so forth for the entire column.
At the end of the loop, we iterate through the dictionary keys (which might be , o, and x) checking the counts. When the count is the same size as a row or column, it's a winning line.
Obviously if there's no win found, we zero the tally and move to the next column/row with the outer-loop.
I have a matrix named IMG, it is a n * m * 3 shaped matrix (an hsv image). What I am trying to achieve is
IF IMG(x, y, 1) < 1/2
THEN IMG(X, Y, 2) = 0.
Logical indexing looks like a solution but with that way we can only access the condition index (IMG(x, y, 1)). With the code below I am changing first indices of the pixels but I want to change second one.
IMG( IMG(:, :, 1) > 1/2 ) = 0;
Thanks for your help.
One simple solution is to extract the whole plane, modify it, then put it back:
s = IMG(:, :, 2);
s(IMG(:, :, 1) > 1/2) = 0;
IMG(:, :, 2) = s;
It is also possible to play around with linear indices, which is more generic, but also more complex:
index = find(IMG(:, :, 1) > 1/2);
offset = size(IMG, 1) * size(IMG, 2);
IMG(index + offset) = 0;
You can multiply the image by a mask:
IMG(:, :, 2) = IMG(:, :, 2) .* (IMG(:, :, 1) <= (1/2)) ;
Or use compound assignment:
IMG(:, :, 2) .*= IMG(:, :, 1) <= (1/2);
Another fast option is reshaping the array:
sz =size(IMG) ;
IMG = reshape(IMG, [], 3);
IMG(IMG(:,1)>1/2, 1), 2) = 0;
IMG = reshape(IMG, sz) ;
Other, possibly less efficient, option is using ifelse :
IMG(:, :, 2) = ifelse(IMG(:, :, 1) > 1/2, 0, IMG(:, :, 2) ) ;
looking for another one-line solution without any intermediate holding variable, the following was proposed for a multi-dimensional array on the Octave Help list:
a( (a(:,:,3)<.5) & shiftdim(1:size(a,3)==2,-1) ) = 0
for example:
>> a = rand(2,3,3)
a =
ans(:,:,1) =
0.63416 0.28912 0.33463
0.76642 0.51474 0.28130
ans(:,:,2) =
0.99748 0.26000 0.45671
0.73153 0.44499 0.24099
ans(:,:,3) =
0.94726 0.77252 0.12698
0.27069 0.46458 0.55833
>> a( (a(:,:,3)<.5) & shiftdim(1:size(a,3)==2,-1) ) = 0
a =
ans(:,:,1) =
0.63416 0.28912 0.33463
0.76642 0.51474 0.28130
ans(:,:,2) =
0.99748 0.26000 0.00000
0.00000 0.00000 0.24099
ans(:,:,3) =
0.94726 0.77252 0.12698
0.27069 0.46458 0.55833
This is the query, simplified.
SELECT `a`, TRUNCATE(`b` / 1000, 3) AS `b`
FROM (
...
) AS `m`
GROUP BY `a`
ORDER BY `a`
What i'm trying to do is change the number of decimal places (actual 3) based on the value of b.
So i tried this:
SELECT `a`, TRUNCATE(`b` / 1000, IF(`b` < 10, 2, 3)) AS `b` ...
and this
SELECT `a `, IF(`b ` < 10, TRUNCATE(`b ` / 1000, 2), TRUNCATE(`b ` / 1000, 3)) AS `b `
If b is less than 10, i want 3 decimal places, otherwise 2.
But this doesn't seem to work ...
Resources : https://dev.mysql.com/doc/refman/8.0/en/control-flow-functions.html#function_if
just change the values position that you put in your query
SELECT `a `, IF(b < 10, TRUNCATE(b / 1000, 3), TRUNCATE(b / 1000, 2))
AS b
if(a<1,2,3) means if a<1 then 2 will come as a value in your result so you have to switch your values position
use round
SELECT a , IF(b < 10, round((b / 1000), 2), round((b / 1000), 3) ) AS b
The ROUND() function rounds a number to a specified number of decimal places.
example SELECT ROUND(345.156, 2); result = 345.16
SELECT ROUND(345.156, 2); result = 345.156
If you don't want round then TRUNCATE will shown 0.00 in case of b value less than 10, so what do you mean by not working ?
You need 3 decimal place when b<10 so you have to change the position of yours query result
You have misplaced the order of queries to run, in case of true/false evaluation in If(). Following may work:
SELECT `a `,
IF(`b ` < 10,
TRUNCATE(`b ` / 1000, 3),
TRUNCATE(`b ` / 1000, 2)
) AS `b `
I am writing the following octave code:
function p = predict(Theta1, Theta2, X)
m = size(X, 1);
num_labels = size(Theta2, 1);
global a=zeros(size(Theta2, 2), m);
global delta=zeros(m, 1);
p = zeros(size(X, 1), 1);
X=[ones(size(X,1),1) X];
a=sigmoid(Theta1*X');
a=[ones(1,size(X,1));a];
[delta p]=max(sigmoid(Theta2*a))';
It gives me the error: "element number 2 undefined in return list".
The error occurs when I use delta in the last line to store max values.
I have searched a lot but couldn't find any relevant answer.
The line
[delta p] = max( sigmoid( Theta2*a ) )'; # transpose operator over the result
is equivalent to
[delta p] = transpose( max( sigmoid( Theta2*a ) ); # transpose function over the result
which means you are trying to get a "two-output" result out of this transpose operation, which fails, since the transpose function only returns one output, therefore octave is informing you that it cannot find a second output in the 'results' list.
Presumably you either meant to do something along the lines of:
[delta p] = max( sigmoid( Theta2*a )' );
and misplaced the transpose operator, or you actually did want to obtain the maxima and their indices as a column vector, in which case you need to do this in two steps, i.e.
[delta p] = max( sigmoid( Theta2*a ) );
ColVector = [delta p]';
PS. Incidentally, you should use .' instead of ' as the transpose operator. ' is not the transpose operator, it's the "conjugate transpose" one.