how to create this matrix without using for loop? - arrays

I want to create a N*N matrix A.
when n = 4
2 0 -2 0
2 0 2 0
0 2 0 -2
0 2 0 2
when n = 8
2 0 0 0 -2 0 0 0
2 0 0 0 2 0 0 0
0 2 0 0 0 -2 0 0
0 2 0 0 0 2 0 0
0 0 2 0 0 0 -2 0
0 0 2 0 0 0 2 0
0 0 0 2 0 0 0 -2
0 0 0 2 0 0 0 2
I can create this using nested for loop, but how to achieve it more efficiently? Are there any methods without for loop?
Thanks

Here's one way with bsxfun -
A = zeros(n);
idx = bsxfun(#plus,[0:(n/2)-1]*((n+3)-1),[1:2].');
A(idx) = 2;
A(idx+numel(A)/2) = -2;
Sample runs -
Case #1 :
>> n = 4;
>> A
A =
2 0 -2 0
2 0 -2 0
0 2 0 -2
0 2 0 -2
Case #2 :
>> n = 8;
>> A
A =
2 0 0 0 -2 0 0 0
2 0 0 0 -2 0 0 0
0 2 0 0 0 -2 0 0
0 2 0 0 0 -2 0 0
0 0 2 0 0 0 -2 0
0 0 2 0 0 0 -2 0
0 0 0 2 0 0 0 -2
0 0 0 2 0 0 0 -2

You can do it like that:
[reshape([repmat([ 2;2;zeros(n,1)],n/2-1,1); 2;2],n,n/2) ...
reshape([repmat([-2;2;zeros(n,1)],n/2-1,1);-2;2],n,n/2) ]
This only will work, if n is a power of two, obviously.
[EDIT]
It might be faster to use
[reshape([repmat([ 2;2;zeros(n,1)],n/2-1,1); 2;2; ...
repmat([-2;2;zeros(n,1)],n/2-1,1);-2;2] ,n,n) ]
[EDIT2]
This is only a good idea, if you have n of moderate size. If you need really big matrices, you should use sparse matrices. In this case a loop is what you want.

Related

What is wrong with my sudoku generate code in c?

That's my homework, making a sudoku game. I have done my algorithm but it's entering infinite loop. I didn't understand why.
I am trying create a random number and control it for find true number. Checking all columns and rows for find same number as like as our random number if it is, it's changing test number and if test has changed trying find another number for true number. Simple sudoku logic.
#include <stdio.h>
#include <stdlib.h>
int main() {
srand(time(NULL));
int num, col, row, row2, col2, test = 0;
int sudo[9][9] = {{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0}};
for (row = 0; row <= 8; row++) {
for (col = 0; col <= 8; col++) {
do {
test = 0;
num = rand() % 9 + 1;
//control
for (col2 = 0; col2 <= 8; col2++) {
if (num == sudo[col2][row]) {
test++;
}
}
for (row2 = 0; row2 <= 8; row2++) {
if (num == sudo[col][row2]) {
test++;
}
}
} while (test > 0);
sudo[col][row] = num;
}
}
//print
for (row = 0; row <= 8; row++) {
for (col = 0; col <= 8; col++) {
printf(" %d ", sudo[col][row]);
if (col == 2 || col == 5) {
printf(" | ");
}
}
if (row == 2 || row == 5) {
printf("\n---------------------------------");
}
printf("\n");
}
}
Your algorithm is broken, and I can demonstrate why. If it were possible to fill in a sudoku puzzle this way, it would also be trivial to solve a sudoku puzzle this way, which it is not.
Essentially your code boils down to the following. I've added early exits on the inner for-loops to stop searching once we find the number already in the current row or column (and actually made sense of what 99.9% of the world thinks of concerning "rows" and "columns" in a NxN matrix):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NSIZE 9
void print_matrix(int const ar[][NSIZE])
{
for (size_t i=0; i<NSIZE; ++i)
{
for (size_t j=0; j<NSIZE; ++j)
{
fputc('0' + ar[i][j], stdout);
fputc(' ', stdout);
}
fputc('\n', stdout);
}
}
int main()
{
srand((unsigned)time(NULL));
int sudo[NSIZE][NSIZE] = {{0}};
int row, col;
for(row=0;row<NSIZE;++row)
{
for(col=0;col<NSIZE;++col)
{
int row2 = 0, col2 = 0, num;
printf("Trying ");
do
{
num = rand()%9+1;
printf("%d ", num);
for(row2=0; row2<NSIZE && num!=sudo[row2][col]; ++row2);
for(col2=0; col2<NSIZE && num!=sudo[row][col2]; ++col2);
}
while (row2 < NSIZE || col2 < NSIZE);
fputc('\n', stdout);
sudo[row][col] = num;
printf("sudo[%d][%d] = %d\n", row, col, num);
print_matrix(sudo);
}
}
}
As the loops progress, we report what number we're trying, and what the matrix looks like upon placement of a keeper. For example, a test run of the above initially can look like this:
Trying 8
sudo[0][0] = 8
8 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 1
sudo[0][1] = 1
8 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 9
sudo[0][2] = 9
8 1 9 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 6
sudo[0][3] = 6
8 1 9 6 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 3
sudo[0][4] = 3
8 1 9 6 3 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 4
sudo[0][5] = 4
8 1 9 6 3 4 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 4 6 7
sudo[0][6] = 7
8 1 9 6 3 4 7 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 1 3 1 3 4 1 3 8 4 9 3 8 1 4 7 9 3 8 8 8 4 9 6 5
sudo[0][7] = 5
8 1 9 6 3 4 7 5 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
and this continues for perhaps a while. But eventually, unless you get extraordinarily lucky, the following is bound to happen (and this one went pretty deep before the wheels fell off):
Trying 1 6 3 4
sudo[6][6] = 4
8 1 9 6 3 4 7 5 2
1 3 5 4 8 6 2 7 9
3 6 4 8 7 9 5 2 1
7 9 1 2 4 5 3 8 6
4 7 3 9 2 8 6 1 5
5 4 2 3 6 1 8 9 7
6 8 7 1 9 3 4 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Note we're about to try and populate sudo[6][7]. To do that we must find a number that is not in the sudo[r][7] column already, nor the sudo[6][c] row. But looking at the numbers already in those positions.
sudo[r][7] : {5,7,2,8,1,9}
sudo[6][c] : {6,8,7,1,9,3,4}
Therefore we're looking for a number from 1..9 that is NOT in: {1,2,3,4,5,6,7,8,9}, which we're NEVER going to find.
The algorithm is broken. There is a reason backtracking is used for tasks like this.

Making two matrix from one

I have a matrix that I would like to split into two separate matrices based on a set of conditions.
The input matrix can be generated with the following code:
lbits = 8;
ntags = 10;
k = randi(lbits,1,ntags);
Tag = zeros(lbits,ntags);
Tag(lbits*(find(k)-1) + k)=1;
TagAnswer = Tag';
Which returns:
TagAnswer =
0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0
My conditions are:
If place of bit '1' is on position lbits/2 or higher, add the row to matrix A
If place of bit '1' is less then position lbits/2, add the row to matrix B
With the above TagAnswer I want the 2nd, 5th and 7th rows to be moved into B and the remaining rows moved into matrix A
Assuming my edit is correct, you can use the row and column outputs of find to index TagAnswer and pull the rows based on your conditions:
% Generate sample data
lbits = 8;
ntags = 10;
k = randi(lbits,1,ntags);
Tag = zeros(lbits,ntags);
Tag(lbits*(find(k)-1) + k)= 1;
TagAnswer = Tag';
% Find bit locations and distribute rows accordingly
[r, c] = find(TagAnswer);
A = TagAnswer(r(c>=(lbits/2)), :);
B = TagAnswer(r(c<(lbits/2)), :);
For my test case I have:
TagAnswer =
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
A =
0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1
B =
0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 1 0 0 0 0 0
Edit: Because MATLAB stores data column-major, find also works column-major and will likely lose the row ordering. If it important to preserve the row ordering of TagAnswer in A and B you can use sort after the find call:
[r, sortidx] = sort(r);
c = c(sortidx);

The fastest way to set up sparse matrix in matlab

I am working with iterative methods, and thus with large sparse matrices.
For instance, I want to set up a matrix like this:
1 1 0 0 1 0 0 0 0 0
1 1 1 0 0 1 0 0 0 0
0 1 1 1 0 0 1 0 0 0
0 0 1 1 1 0 0 1 0 0
1 0 0 1 1 1 0 0 1 0
0 1 0 0 1 1 1 0 0 1
So that only certain diagonals are non-zero. In my programming, I will be working with much larger matrix sizes, but Idea is the same: Only a few diagonals are non-zero, all other entries are zeros.
I know, how to do it in for loop, but it seems to be not effective, if the matrix size is large. Also I work with symmetric matrices.
I would appreciate, if you provide me a code for my sample matrix along with description.
You want spdiags:
m = 6; %// number of rows
n = 10; %// number of columns
diags = [-4 -1 0 1 4]; %// diagonals to be filled
A = spdiags(ones(min(m,n), numel(diags)), diags, m, n);
This gives:
>> full(A)
ans =
1 1 0 0 1 0 0 0 0 0
1 1 1 0 0 1 0 0 0 0
0 1 1 1 0 0 1 0 0 0
0 0 1 1 1 0 0 1 0 0
1 0 0 1 1 1 0 0 1 0
0 1 0 0 1 1 1 0 0 1

Check all diags in square matrix for true

I am trying to check if in a square matrix there is more than one true value in all possible diagonals and anti-diagonals, and return true, otherwise false.
So far I have tried as following but is not covering all possible diagonals:
n=8; %matrix dimension 8 x 8
diag= sum(A(1:n+1:end));
d1=diag>=2;
antiDiag=sum(A(n:n-1:end));
d2=antiDiag>=2;
if ~any(d1(:)) || ~any(d2(:))
res= true;
else
res=false;
end
this is a false:
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
this is a true:
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
Since these are my first steps in using Matlab, is there a specific function or a better way to achieve the result I am looking for?
To detect if there are more than one nonzero value in any diagonal or anti-diagonal (not just the main diagonal and antidiagonal): get the row and column indices of nonzero values, ii and jj; and then check if any value of ii-jj (diagonals) or ii+jj (anti-diagonals) is repeated:
[ii, jj] = find(A);
res = (numel(unique(ii-jj)) < numel(ii)) || (numel(unique(ii+jj)) < numel(ii));
One approach:
n=8; %// size of square matrix
A = logical(randi(2,n)-1); %// Create a logical matrix of 0s and 1s
d1 = sum(A(1:n+1:end)); %// sum all the values of Main diagonal
d2 = sum(A(n:n-1:end-1)); %// sum all the values of Main anti-diag
result = d1>=2 | d2>=2 %// result is true when any one of them is > than or = to 2
Sample run:
Inputs:
>> A
A =
0 1 1 1 1 0 1 0
0 1 1 1 1 1 0 0
0 1 0 1 1 0 0 1
0 1 1 0 1 1 0 0
0 1 0 1 1 0 0 1
1 0 0 0 1 1 0 1
1 1 1 1 1 1 0 0
1 1 1 1 0 0 0 1
Output:
result =
1
Note: This approach considers only the Main diag and Main Anti-Diag (considering the example you provided). If you want for all possible diags, the other answer from Luis Mendo is the way to go
Using #Santhan Salai's generating technique, we can use the diag function (to pull out the main diagonal of the matrix), the fliplr to flip over the center column and any to reduced to a single value.
n=8; %// size of square matrix
A = logical(randi(2,n)-1); %// Create a logical matrix of 0s and 1s
any([diag(A) ; diag(fliplr(A))])

Adjacency matrix of binary tree of depth 4 in C

How would the adjacency matrix of binary tree of depth 4 in C look like? The depth of a node is defined as its distance from the root.
I know a is at depth zero e is at depth 2
a
/ \
b c
/ \ / \
d e f g
/ \ / \ / \ / \
h i j k l m n o
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
a b c d e f g h i j k l m n o
a 1 1 0 0 0 0 0 0 0 0 0 0 0 0
b 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0
c 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0
d 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0
e 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0
f 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0
g 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1
h 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
i 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
j 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
k 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
l 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
m 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
n 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
o 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
Just an observation. Holds true in general.
If you have a complete binary tree, by which I mean all internal nodes have two children, and all leaves at same depth. And if you number them starting from 1
i.e. in your case
a = 1; b = 2; c = 3 ....
For any node x -> i
It's children will be 2*i and 2*i + 1
And it's parent will be floor(i/2)
In your case, you can just hard-code it since you have only depth = 4

Resources