Algorithm for progressive matrix - algorithm

I want to construct a matrix like so:
[ 0 1 2 3 4 5 ....
1 2 3 4 5 6 ....
2 3 4 5 6 7 ....
3 4 5 6 7 8 ....
4 5 6 7 8 9 ....
5 6 7 8 9 10 ... ] etc
The main goal is to use the algorithm to put to the power the elements of an already existing matrix.
I am programming in Fortran, and I used the following code but it's not working:
do i = 1, m+1
do j = 1, m+1
do while ( w < 2*m )
if ( i > j ) then
ma(i,j) = 0
else
w = i-1
ma(i, j) = w
w = w +1
end if
end do
end do
end do

I suggest you to use an implied-do in the array constructor syntax, possibly initialized in the same declaration:
integer, parameter :: n = 10, m = 5
integer :: i, j
integer :: ma(m,n) = reshape([((i+j, j=0, m-1), i=0, n-1)], [m,n])
The [...] syntax is posible in Fortran 2003 or higher. (/.../) should be used otherwise. My result with gfortran v7.1.1 is:
do i = 1, m
print *, ma(i, :)
end do
$gfortran test.f90 -o main
$main
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10 11
3 4 5 6 7 8 9 10 11 12
4 5 6 7 8 9 10 11 12 13
Note: The initialization in the declaration would only be possible if n and m are constants (parameter). You could initialize it normally in the program body, otherwise, with the same implied-do syntax.
If you plan to read the values of m and n at runtime, you should make ma an allocatable array.

While there is nothing wrong with Rodrigo's answer personally I think it much clearer to just use two loops
ian#eris:~/work/stackoverflow$ cat floyd.f90
Program yes
Implicit None
Integer, Parameter :: n = 5
Integer, Dimension( 1:n, 1:n ) :: elp
Integer :: base, offset
Integer :: i, j
Do i = 1, n
base = i - 1
Do j = 1, n
offset = j - 1
elp( j, i ) = base + offset
End Do
End Do
Do j = 1, n
Write( *, '( 1000( i3, 1x ) )' ) elp( j, : )
End Do
End Program yes
ian#eris:~/work/stackoverflow$ gfortran -Wall -Wextra -std=f2003 -fcheck=all -O floyd.f90 -o genesis
ian#eris:~/work/stackoverflow$ ./genesis
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8

I've seen that others already made an algorithm that solves your problem. But i also bring another algorithm that works for a non-square matrix. NI is the number of columns of the matrix, and NJ is the number of lines. MAT is the matrix you want.
PROGRAM MATRIX
IMPLICIT NONE
INTEGER :: I, J, NI, NJ
INTEGER, ALLOCATABLE :: MAT(:,:)
NI = 8
NJ = 5
ALLOCATE(MAT(NI,NJ))
DO I = 1, NI
MAT(I,1) = I-1
ENDDO
DO J = 2,NJ
MAT(:,J) = MAT(:,J-1) + 1
ENDDO
DO J = 1, NJ
WRITE(*,'(8I3)') MAT(:,J)
ENDDO
END PROGRAM

Thanks for the feedback, I managed to do it using the following code:
do i = 1, m+1
w = i-1
do j = 1, m+1
ma(i, j) = u**w
w = w+1
end do
end do
I would like to state that i'm using Fortran 90 and only 90 because of my circumstances, otherwise I would've went with c++, (university life !!).
Please note that I used the desired series to put to the power the elements of the matrix.
Finally, I noticed some "complex" answers maybe, or maybe I'm just a beginner, but i would really love to learn if there are some rules and or dos and don'ts and or advice to get better at coding ( scientific code, not development code).
Thank you very much for the feed back, and waiting for any responses.

Related

What's the best practice for subtracting a constant from say col 2 in Octave 3x n Matrix

Here, I subtract 2000 from column 2 and return the complete 3 column vector...
This "works"; but, isn't it processing the matrix 3 times?
xx = [X(:,1),X(:,2) .-2000,X(:,3)]
Best practice please... ;-0
The simplest way to do this operation is to simply:
X(:,2) -= 2000;
which is also a lot easier to read. This will modify the second column X "in place". If you want to make a copy of it where the second column is subtracted, then simply:
xx = X;
xx(:,2) -= 2000;
An example:
octave-cli-3.8.2> X = randi (9, 5, 3)
X =
1 4 4
1 2 6
8 4 3
7 7 1
7 7 2
octave-cli-3.8.2> X(:,2) -= 10
X =
1 -6 4
1 -8 6
8 -6 3
7 -3 1
7 -3 2

Division algorithm with decimal bignum

EDIT: I rebased my bignum class to use std::bitset and I just implemented long division fine. I just didn't know any class to store bits. (like std::bitset)
I'm making a bignum class with std::string to use decimal characters as internal representation. I tried implementing division with a simple algorithm:
while N ≥ D do
N := N - D
end
return N
And of course it was slow. I tried implementing long division but that was too hard to do with decimal characters.
Thanks in advance.
Instead of subtracting D very often you could try to find the highest value of the form
D^2n and sub this. Than repeat that steps with the remaining value until the remaining is less than D.
Pseudocode
0 result=0
1 powerOfD = D
2 while (powerOfD*powerOfD<N)
3 powerOfD=powerOfD*powerOfD
4 result = result+powerOfD/D, N=N-powerOfD;
5 if(N>D)
6 goto 1
7 return result
Example 31/3 (N=31, D=3)
0 result=0
1 powerD = 3;
2 3*3 < 31 TRUE
3 powerOfD= 3*3;
2 9*9 < 31 FALSE
4 result=0+9/3; N=31 - 9
5 22> 3 TRUE
6 goto 1
1 powerD = 3
2 3*3 < 22 TRUE
3 powerOfD= 3*3;
2 9*9 < 31 FALSE
4 result=3+9/3; N=22 - 9
5 13> 3 TRUE
6 goto 1
1 powerD = 3
2 3*3 < 13 TRUE
3 powerOfD= 3*3;
2 9*9 < 31 FALSE
4 result=6+9/3; N=13 - 9
5 4> 3 TRUE
6 goto 1
1 powerD = 3
2 3*3 < 4 ALSE
4 result=9+3/3; N=4-3
5 1> 3 FALSE
7 return 10

What does the % symbol mean in Ruby? [duplicate]

This question already has answers here:
How Does Modulus Divison Work
(19 answers)
Closed 8 years ago.
What does the % symbol mean in Ruby? For example, I use the following code:
puts "Roosters #{100 - 25 * 3 % 4}"
And get the following output:
97
Where the deuce did the 97 come from? I've looked up what the modulo operator is and still have no idea what it does in this simple mathematics example.
Modulo operator.
It does division and returns the remainder. So, in your case, 75 / 4 is 18 with a remainder of 3.
25 * 3 = 75
75 % 4 = 3 (the remainder)
100 - 3 = 97
modulo - divide with remainder
divide, and take the remainder from the integer division.
10 / 3 = 3 (with remainder 1 that we discard with integer division)
10 % 3 = 1 (the part we normally discard is the part we are interested in with mod)
It is also used to create cycles. If we had a sequence of 1 to N, we could mod it by M and produce a cycle. Assume M = 3 again
for n in 0..10
m = n % 3
puts "#{n} mod 3 = #{m}"
end
0 mod 3 = 0
1 mod 3 = 1
2 mod 3 = 2
3 mod 3 = 0
4 mod 3 = 1
5 mod 3 = 2
6 mod 3 = 0
7 mod 3 = 1
8 mod 3 = 2
9 mod 3 = 0
10 mod 3 = 1

Transpose and reshape a 3d array in matlab

Suppose I have an array X of size n by p by q. I would like to reshape it as a matrix with p rows, and in each row put the concatenation of the n rows of size q, resulting in a matrix of size p by nq.
I managed to do it with a loop but it takes a while say if n=1000, p=300, q=300.
F0=[];
for k=1:size(F,1)
F0=[F0,squeeze(X(k,:,:))];
end
Is there a faster way?
I think this is what you want:
Y = reshape(permute(X, [2 1 3]), size(X,2), []);
Example with n=2, p=3, q=4:
>> X
X(:,:,1) =
0 6 9
8 3 0
X(:,:,2) =
4 7 1
3 7 4
X(:,:,3) =
4 7 2
6 7 6
X(:,:,4) =
6 1 9
1 4 3
>> Y = reshape(permute(X, [2 1 3]), size(X,2), [])
Y =
0 8 4 3 4 6 6 1
6 3 7 7 7 7 1 4
9 0 1 4 2 6 9 3
Try this -
reshape(permute(X,[2 3 1]),p,[])
Thus, for code verification, one can look into a sample case run -
n = 2;
p = 3;
q = 4;
X = rand(n,p,q)
F0=[];
for k=1:n
F0=[F0,squeeze(X(k,:,:))];
end
F0
F0_noloop = reshape(permute(X,[2 3 1]),p,[])
Output is -
F0 =
0.4134 0.6938 0.3782 0.4775 0.2177 0.0098 0.7043 0.6237
0.1257 0.8432 0.7295 0.2364 0.3089 0.9223 0.2243 0.1771
0.7261 0.7710 0.2691 0.8296 0.7829 0.0427 0.6730 0.7669
F0_noloop =
0.4134 0.6938 0.3782 0.4775 0.2177 0.0098 0.7043 0.6237
0.1257 0.8432 0.7295 0.2364 0.3089 0.9223 0.2243 0.1771
0.7261 0.7710 0.2691 0.8296 0.7829 0.0427 0.6730 0.7669
Rather than using vectorization to solve the problem, you could look at the code to try and figure out what may improve performance. In this case, since you know the size of your output matrix F0 should be px(n*q), you could pre-allocate memory to F0 and avoid the constant resizing of the matrix at each iteration of the for loop
n=1000;
p=300;
q=300;
F0=zeros(p,n*q);
for k=1:size(F,1)
F0(:,(k-1)*q+1:k*q) = squeeze(F(k,:,:));
end
While probably not as efficient as the other two solutions, it is an alternative. Try the above and see what happens!

Identify gaps in repeated sequences

I have a vector that should contain n sequences from 00 to 11
A = [00;01;02;03;04;05;06;07;08;09;10;11;00;01;02;03;04;05;06;07;08;09;10;11]
and I would like to check that the sequence "00 - 11 " is always respected (no missing values).
for example if
A =[00;01;02; 04;05;06;07;08;09;10;11;00;01;02;03;04;05;06;07;08;09;10;11]
(missing 03 in the 3rd position)
For each missing value I would like to have back this information in another vector
missing=
[value_1,position_1;
value_2, position_2;
etc, etc]
Can you help me?
For sure we know that the last element must be 11, so we can already check for this and make our life easier for testing all previous elements. We ensure that A is 11-terminated, so an "element-wise change" approach (below) will be valid. Note that the same is true for the beginning, but changing A there would mess with indices, so we better take care of that later.
missing = [];
if A(end) ~= 11
missing = [missing; 11, length(A) + 1];
A = [A, 11];
end
Then we can calculate the change dA = A(2:end) - A(1:end-1); from one element to another, and identify the gap positions idx_gap = find((dA~=1) & (dA~=-11));. Now we need to expand all missing indices and expected values, using ev for the expected value. ev can be obtained from the previous value, as in
for k = 1 : length(idx_gap)
ev = A(idx_gap(k));
Now, the number of elements to fill in is the change dA in that position minus one (because one means no gap). Note that this can wrap over if there is a gap at the boundary between segments, so we use the modulus.
for n = 1 : mod(dA(idx_gap(k)) - 1, 12)
ev = mod(ev + 1, 12);
missing = [missing; ev, idx_gap(k) + 1];
end
end
As a test, consider A = [5 6 7 8 9 10 3 4 5 6 7 8 9 10 11 0 1 2 3 4 6 7 8]. That's a case where the special initialization from the beginning will fire, memorizing the missing 11 already, and changing A to [5 6 ... 7 8 11]. missing then will yield
11 24 % recognizes improper termination of A.
11 7
0 7 % properly handles wrap-over here.
1 7
2 7
5 21 % recognizes single element as missing.
9 24
10 24
which should be what you are expecting. Now what's missing still is the beginning of A, so let's say missing = [0 : A(1) - 1, 1; missing]; to complete the list.
This will give you the missing values and their positions in the full sequence:
N = 11; % specify the repeating 0:N sub-sequence
n = 3; % reps of sub-sequence
A = [5 6 7 8 9 10 3 4 5 6 7 8 9 10 11 0 1 2 3 4 6 7 8]'; %' column from s.bandara
da = diff([A; N+1]); % EDITED to include missing end
skipLocs = find(~(da==1 | da==-N));
skipLength = da(skipLocs)-1;
skipLength(skipLength<0) = N + skipLength(skipLength<0) + 1;
firstSkipVal = A(skipLocs)+1;
patchFun = #(x,y)(0:y)'+x - (N+1)*(((0:y)'+x)>N);
patches = arrayfun(patchFun,firstSkipVal,skipLength-1,'uni',false);
locs = arrayfun(#(x,y)(x:x+y)',skipLocs+cumsum([A(1); skipLength(1:end-1)])+1,...
skipLength-1,'uni',false);
Then putting them together, including any missing values at the beginning:
>> gapMap = [vertcat(patches{:}) vertcat(locs{:})-1]; % not including lead
>> gapMap = [repmat((0 : A(1) - 1)',1,2); gapMap] %' including lead
gapMap =
0 0
1 1
2 2
3 3
4 4
11 11
0 12
1 13
2 14
5 29
9 33
10 34
11 35
The first column contains the missing values. The second column is the 0-based location in the hypothetical full sequence.
>> Afull = repmat(0:N,1,n)
>> isequal(gapMap(:,1), Afull(gapMap(:,2)+1)')
ans =
1
Although this doesn't solve your problem completely, you can identify the position of missing values, or of groups of contiguous missing values, like this:
ind = 1+find(~ismember(diff(A),[1 -11]));
ind gives the position with respect to the current sequence A, not to the completed sequence.
For example, with
A =[00;01;02; 04;05;06;07;08;09;10;11;00;01;02;03; ;06;07;08;09;10;11];
this gives
>> ind = 1+find(~ismember(diff(A),[1 -11]))
ind =
4
16

Resources