How can I build a decreasing lower triangular matrix? [closed] - arrays

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Do you know if it is possible to get the following triangular matrix
[ N:-1:1; (N-1):-1:0; (N-2):-1:0 0; (N-3):-1:0 0 0; ....] without writing every line with horzcat and without using a loop?
thanks all
Fred

Is this what you want?
N = 8;
result = flipud(tril(toeplitz(1:N)));
This gives
result =
8 7 6 5 4 3 2 1
7 6 5 4 3 2 1 0
6 5 4 3 2 1 0 0
5 4 3 2 1 0 0 0
4 3 2 1 0 0 0 0
3 2 1 0 0 0 0 0
2 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0

Maybe something like this:
N=10;
M=triu(gallery('circul',N)).'
M =
1 0 0 0 0 0 0 0 0 0
2 1 0 0 0 0 0 0 0 0
3 2 1 0 0 0 0 0 0 0
4 3 2 1 0 0 0 0 0 0
5 4 3 2 1 0 0 0 0 0
6 5 4 3 2 1 0 0 0 0
7 6 5 4 3 2 1 0 0 0
8 7 6 5 4 3 2 1 0 0
9 8 7 6 5 4 3 2 1 0
10 9 8 7 6 5 4 3 2 1
Or did you want this:
M=fliplr(triu(gallery('circul',N)))
M =
10 9 8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1 0
8 7 6 5 4 3 2 1 0 0
7 6 5 4 3 2 1 0 0 0
6 5 4 3 2 1 0 0 0 0
5 4 3 2 1 0 0 0 0 0
4 3 2 1 0 0 0 0 0 0
3 2 1 0 0 0 0 0 0 0
2 1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
I couldn't really tell from your code sample which direction you wanted this to go.

The power of bsxfun compels you!
[[N:-1:1]' reshape(repmat([N-1:-1:1]',1,N).*bsxfun(#ge,[1:N-1]',1:N),N,[])]
Sample run -
>> N = 8;
>> [[N:-1:1]' reshape(repmat([N-1:-1:1]',1,N).*bsxfun(#ge,[1:N-1]',1:N),N,[])]
ans =
8 7 6 5 4 3 2 1
7 6 5 4 3 2 1 0
6 5 4 3 2 1 0 0
5 4 3 2 1 0 0 0
4 3 2 1 0 0 0 0
3 2 1 0 0 0 0 0
2 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
This is basically inspired by this another bsxfun-based solution to a very similar question - Replicate vector and shift each copy by 1 row down without for-loop. There you can see similar solutions and related benchmarks, as it seems performance is a concern here.

Related

How to do padding for a matrix

I am trying to do the padding for a basic matrix.
For example, I have a 3 * 3 matrix and I want to pad it to 7 * 7 matrix:
3x3 Matrix
1 2 3
4 5 6
7 8 9
Is there any efficient way to add 2 padding to on the matrix?
7x7 Matrix After Padding
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 1 2 3 0 0
0 0 4 5 6 0 0
0 0 7 8 9 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

Looping through an array to check a condition

I'm using a FOR loop to loop through an array to check a condition but it seems to duplicate the variables I want to print.
Here's my code:
/*Printing the matrix*/
for(row=0;row<15;row++)
{
for(col=0;col<8;col++)
{
for(a=0;a<sizeof(row_sel)/(sizeof(row_sel[0]));a++)
{
if(row==row_sel[a] && col==col_sel[a])
{
printf("|%d|",matrix[row][col]);
}
else
{
printf(" %d ",matrix[row][col]);
}
}
}
printf("\n");
}
What I'm trying to print is:
|0| 6 7 3 6 6 9 5
0 0 0 0 0 0 0 0
2 8 8 4 8 4 0 0
0 0 0 0 0 0 0 0
5 0 8 7 9 5 5 3
0 0 0 0 0 0 0 0
2 7 8 5 3 3 8 6
0 0 0 0 0 0 0 0
6 6 4 2 9 6 2 1
0 0 0 0 0 0 0 0
9 4 0 6 6 7 0 4
0 0 0 0 0 0 0 0
4 3 8 9 0 2 2 7
0 0 0 0 0 0 0 0
0 3 6 7 8 3 5 |2|
But instead I get this output, I don't know why the values are duplicated,the loop should've ended or skipped the statement:
|0| 0 0 1 1 1 2 2 2 7 7 7 7 7 7 3 3 3 6 6 6 1 1 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 6 6 6 3 3 3 2 2 2 0 0 0 4 4 4 2 2 2 9 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
5 5 5 4 4 4 6 6 6 3 3 3 5 5 5 8 8 8 6 6 6 5 5 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
5 5 5 7 7 7 1 1 1 9 9 9 1 1 1 2 2 2 0 0 0 4 4 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
9 9 9 7 7 7 3 3 3 6 6 6 8 8 8 0 0 0 3 3 3 8 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
5 5 5 2 2 2 6 6 6 5 5 5 2 2 2 7 7 7 5 5 5 5 5 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
5 5 5 7 7 7 8 8 8 3 3 3 2 2 2 1 1 1 1 1 1 6 6 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
9 9 9 6 6 6 9 9 9 7 7 7 2 2 2 6 6 6 2 2 2 5 |5| 5
Any tips to where I went wrong? Any help is quite appreciated.
Your problem:
You print each value of the matrix for every a, but you only want to print it once.
The solution:
You have to move the if-else statement out of the innermost loop:
for(row=0;row<15;row++)
{
for(col=0;col<8;col++)
{
bool foundMatch = false;
for(a=0;!foundMatch && a<sizeof(row_sel)/(sizeof(row_sel[0]));a++)
{
foundMatch = row==row_sel[a] && col==col_sel[a];
}
if(foundMatch)
{
printf("|%d|",matrix[row][col]);
}
else
{
printf(" %d ",matrix[row][col]);
}
}
printf("\n");
}
Why/How it works:
The inner loop will run until foundMatch is true, or a gets out of range.
foundMatch is set to true if there is any a for which row==row_sel[a] && col==col_sel[a] is true.
|%d| will print if foundMatch is true.

How to find elements in an array based on a search from another array

Imagine that i have two arrays:
a = [1 1 1 1 5 5 5 5 5 5 8 8;
1 1 1 3 5 5 5 5 5 8 8 8;
1 1 3 3 3 5 5 5 8 8 8 8;
1 3 3 3 3 3 5 8 8 8 8 8;
4 4 4 9 9 0 3 3 8 8 8 8;
4 4 4 9 0 0 3 3 3 3 8 8;
4 4 9 9 0 0 0 0 0 0 1 1;
4 9 9 9 0 0 0 0 0 0 1 1;
9 9 9 9 9 0 0 0 7 7 7 7];
b = [4 5 7];
I want ans like this :
ans =
0 0 0 0 1 1 1 1 1 1 0 0
0 0 0 0 1 1 1 1 1 0 0 0
0 0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0
1 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 0 1 1 1 1
The function ismember does exactly that:
ismember(a, b)
ans =
9×12 logical array
0 0 0 0 1 1 1 1 1 1 0 0
0 0 0 0 1 1 1 1 1 0 0 0
0 0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0
1 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 0 1 1 1 1
Not sure if this is the most efficient but this should work:
c = zeros(size(a));
for i = 1:numel(a)
if ismember(a(i), b(:))
c(i) = 1
end
end
Testing on some smaller arrays:
octave:1> a = [1 1 5 5 8 8;1 5 1 3 5 8]
a =
1 1 5 5 8 8
1 5 1 3 5 8
octave:2> b = [5 8]
b =
5 8
octave:3> c = zeros(size(a));
for i = 1:numel(a)
if ismember(a(i), b(:))
c(i) = 1
end
end
c =
0 0 0 0 0 0
0 1 0 0 0 0
.
.
.
c =
0 0 1 1 1 1
0 1 0 0 1 0
c =
0 0 1 1 1 1
0 1 0 0 1 1

How can I change a scanf("%d",&variable) to receive an argv from the command line in C

I'm trying to modify a portion of a program which currently takes user input during runtime and saves the response to a reference to a variable and instead make it fetch the response as an argv[] when compiling. I can fetch the response from argv, but i'm not sure how to retain the variable reference functionality.
Here is the original code:
printf("\n Enter Variable : ");
scanf("%d",&variable);
Output:
PID BURST ARRIVAL
0 0 12
1 2 4
2 3 1
3 4 2
Enter quantum time : 5
0 2 3 3 7 1 9
Average waiting time = 0.00
Average turn-around = 2.25.
Here is what I have attempted:
variable = argv[1];
Output:
0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1 0 2 0 3 0 1
And:
&variable = argv[1];
Also:
(int*)&variable = argv[1];
The first attempt compiles and runs with the command line input, but the output from the program is broken/different from the original. The second and third attempts give gcc errors about using & as the left operand. Does anyone know how to mimic the original functionality with argv[] instead of scanf()?
scanf is both reading the string and converting it to an integer (the %d). When you use argv[1], you only have the string, but haven't converted it to an integer. You need to use a function like atoi or strtol, like:
variable = strtol(argv[1], NULL, 10);
Or, as #JohnBollinger correctly points out, sscanf also works:
sscanf(argv[1], "%d", &variable);
If you're trying to convert the command line argument to an integer, then I think the functionality you're looking for is in atoi or strtol. But a near drop-in replacement for scanf is sscanf, which reads from a string instead of the standard input.
sscanf(argv[1], "%d", &variable);
The reason your first attempt didn't work is because what you're really doing is converting the char* pointer to an integer. It's not actually reading the content of the string. You were seeing the value of the pointer converted to an int.
Your other two didn't work because &variable is not an lvalue and cannot be assigned to.

how to add a factor to a sequence?

I'm analysing a dataset with some data-mining tools.The response variable has ten levels and I'm trying to create a classifier.
Here comes the problem.When using nnet and bagging function,the result is not that good and the 5th level is even not in the prediction.
I want to use a confusion matrix to analyse the classifier.but as the 5th level is not shown in the prediction I can't get a well-formed matrix.So how can I get a well-formed matrix?i.e. I want a 10*10 matrix.
The confusion matrix:
library("mda")#This is where **confusion** comes from
> confusion(pre.bag$class,CLASS)#here confusion acts like table
true
predicted 1 2 3 4 6 7 8 9 10 5
1 338 9 6 0 5 12 10 1 15 46
2 9 549 1 59 18 0 3 0 0 6
3 18 1 44 0 0 0 2 0 0 4
4 0 1 0 21 0 0 0 0 0 0
6 2 13 0 1 299 2 9 0 0 0
7 5 2 1 0 10 231 6 0 1 0
8 0 0 0 0 0 5 76 0 0 0
9 5 1 0 0 0 0 0 62 0 0
10 7 3 1 0 0 2 1 6 181 16
attr(,"error")
[1] 0.1231743
attr(,"mismatch")
[1] 0.03386642
Try this:
pred <- factor(pre.bag$class, levels=levels(CLASS) )
confusion(pre.bag$class, CLASS)
(Tested with an fda-object.)

Resources