Author: gdjs2, chris, oierVICTOR
Semester: 2022 Fall
In Assignment 1, you are required to finish some simple functions related to POWER(Exponentiation) and MATRIX to help you master the basic C/C++ syntax. As result, you can find a definitely novel way to calculate Fibonacci sequence.
Part 2. Matrix Addition and Matrix Multiplication (50pts)
Part 3. Naive Matrix Exponentiation (15pts)
Part 4. Fast Matrix Exponentiation (15pts)
Part 5. Fibonacci Sequence (20pts)
(You can find an online doc for your tasks via https://cs205-s22.github.io/assign1)
POWER is a critical concept in mathematics. As we know, we can use repeatition to calculate
To help you get started, we will give you the pseudo code for TRADITIONAL and QUICK POWER separately.
TRADITIONAL POWER calculating
Function traditional_power(x, n) -> Integer:
answer <- 1;
REPEAT for n times:
answer = answer * x;
RETURN answer;
The QUICK POWER is a typical application of Divide and Conquer, suppose we need to calculate
- If
$n$ is even, we can recursively derive the result$x^n = x^{n/2}\times x^{n/2}$ . - Otherwise,
$x^n = x^{\lfloor n/2\rfloor} \times x^{\lfloor n/2\rfloor} \times x$ . - The boundary condition is
$x^n = 1$ , when$n == 0$ .
QUICK POWER calculating
Function quick_power_recursion(x, n) -> Integer:
IF n is 0:
RETURN 1;
partition_factor <- quick_power_recursion(x, floor(n/2));
IF n is odd:
RETURN partition_factor * partition_factor * x;
ELSE:
RETURN partition_factor * partition_factor;
Also, we can optimize the recursive version by non-recursive one:
Function quick_power_non_recursion(x, n) -> Integer:
answer <- 1;
power_factor <- x;
WHILE n is not 0:
IF n is odd:
answer <- answer * power_factor;
power_factor <- power_factor * power_factor;
n = floor(n/2);
WHAT YOU SHOULD DO (20 pts in total):
- Read the document CAREFULLY!
- Implement the function
quick_power
(20 pts) inassign1.c
.
ATTENTION:
- NO GRADES will be given unless you implement the correct QUICK POWER!
-
ALL TEST CASES are valid, i.e.,
$x \ge 0 \cap n\ge 0$ . You do not need to handle exceptions. - Because the result
$r$ may be too large. You need to calculate$a$ , in which$a\equiv r ;(\mathrm{mod};10^9+7)$ . i.e., you need to modulo all results by$10^9+7$ when necessary. The constant MODULO has been defined as$10^9+7$ inassign1_mat.h
. You can use the variable directly. - Please pay more attention to your code style. After all this is not ACM-ICPC contest. You will get deduction if your code style is terrible. You can read Google C++ Style Guide, NASA C Style Guide or some other guide for code style.
Matrix is useful in linear algebra and computer science. In this part, you are required to finish several functions corresponding to matrix, including addition and multiplication. We suppose that you all have basic background knowledge about matrix. If not, you can check the website or search the internet by yourself.
We will not introduce the concept of matrix here, but the matrix structure we provide to you in assign1_mat.h
and assign1_mat.c
. You do not need to understand the functions' implementation and the definition of the structure while you need to know how to use the APIs provided to manipulate a matrix.
- Structure
struct matrix
: Structure for matrix. - Function
create_matrix_all_zero
: Create a matrix filled by zeros. - Function
delete_matrix
: Delete the data segment of a matrix. You MUST call this function whenver a matrix is no longer needed. - Function
copy_matrix
: Copy a matrix. Do NOT use=
to copy a matrix. - Funciton
set_by_index
: Set an entry of matrix to a specified value. - Function
get_by_index
: Get the value in an specified entry of matrix.
You can assume the Matrix structure as a two-dimensional array, which has col
and row
. Like the index of array, both col
and row
start from 0. So be careful when you index element by set_by_index
and get_by_index
.
To help you get started, we have finished the scalar multiplication in assign1_mat.c
. It contains some usage of APIs to help you get started . We do following things in scalar_multiplication
function:
- Check whether the size of the result container variable
mat_res
matches the original matrixmat_a
. If the size checking passes, we will continuing the calculation; or return 1 which represents the failing of size checking. - For each entry of the matrix, get the original value, do the multiplication and set to the entry of the result matrix.
- We do the modulo opeartion (
%MODULO
) in the multiplication to prevent integer overflow. You need to follow this rule in the following parts needed to be implemented by yourself.
You need to implement the matrix addition and multiplication.
WHAT YOU SHOULD DO (50 pts in total):
- Read the document and code we provided to you CAREFULLY!
- Implement the function
matrix_addition
(20 pts) andmatrix_multiplication
(30 pts) inassign1.c
.
ATTENTION:
- NO GRADES will be given unless you implement the correct MARTIX ADDITION and MATRIX MULTIPLICATION!
- Do the size checking in the function and show the result of operation by return value. If the return value of your function is not 0, DO NOT modify the values in
mat_res
. - DO the modulo operation(
%MODULO
) during the multiplication and be attention to the overflow! - It is GUARANTEED that
mat_res
is different frommat_a
ormat_b
in both addition and multiplication when we test your functions. But BE SURE you will not call the these functions with the samemat_res
andmat_a
or samemat_res
andmat_b
either!
Till now, we have known quick power and matrix multiplication. Suppose we replace
For example: the traditional method to calculate the Fibonacci Sequence is using a loop and calculating the recursive derivation in
We can transform the recursive formula into matrix multiplication in the following way:
- Construct matrix $\begin{bmatrix} 1 & 1\ 1 & 0\ \end{bmatrix}$
- Suppose there is a vector $\begin{bmatrix} f_{n-1}\ f_{n-2} \end{bmatrix}$
- Do the multiplication between the first matrix and the second vector:
$\begin{bmatrix}
1 & 1\
1 & 0\
\end{bmatrix}
\times
\begin{bmatrix}
f_{n-1}\
f_{n-2}
\end{bmatrix}
=
\begin{bmatrix}
f_{n-1}+f_{n-2}\
f_{n-1}
\end{bmatrix}
=
\begin{bmatrix}
f_{n}\
f_{n-1}
\end{bmatrix}$. We successfully got
$f_{n}$ and the vector which can be used to calculate the next item$f_{n+1}$ . - We can do the multiplication between the first matrix and the vector we got from step 3: $$\begin{bmatrix} 1 & 1\ 1 & 0\ \end{bmatrix} \times \begin{bmatrix} f_{n}\ f_{n-1} \end{bmatrix} = \begin{bmatrix} f_{n}+f_{n-1}\ f_{n} \end{bmatrix} = \begin{bmatrix} f_{n+1}\ f_{n} \end{bmatrix}$$
- If we put the initial value
$f_0$ and$f_1$ into the vector and do the matrix multiplication:
$$ \begin{bmatrix} 1 & 1\ 1 & 0\ \end{bmatrix} \times \begin{bmatrix} f_1=1\ f_0=0\ \end{bmatrix} = \begin{bmatrix} f_2=1\ f_1=1\ \end{bmatrix} $$ - Because the matrix multiplication satisfies the law of association: $$ \begin{bmatrix} 1 & 1\ 1 & 0\ \end{bmatrix} \times \begin{bmatrix} f_2=1\ f_1=1\ \end{bmatrix} = \begin{bmatrix} 1 & 1\ 1 & 0\ \end{bmatrix} \times \begin{bmatrix} 1 & 1\ 1 & 0\ \end{bmatrix} \times \begin{bmatrix} f_1=1\ f_0=0\ \end{bmatrix} = \begin{bmatrix} 1 & 1\ 1 & 0\ \end{bmatrix}^2 \times \begin{bmatrix} f_1=1\ f_0=0\ \end{bmatrix} = \begin{bmatrix} f_3=2\ f_2=1\ \end{bmatrix} $$
- Finally, we got: $$ \begin{bmatrix} f_3\ f_2\ \end{bmatrix} = \begin{bmatrix} 1 & 1\ 1 & 0\ \end{bmatrix}^2 \times \begin{bmatrix} f_1\ f_0\ \end{bmatrix} $$
- It is easy to find: $$\begin{bmatrix} f_n\ f_{n-1}\ \end{bmatrix} = \begin{bmatrix} 1 & 1\ 1 & 0\ \end{bmatrix}^{n-1} \times \begin{bmatrix} f_1\ f_0\ \end{bmatrix} $$
We will focus on how to calculate the exponentiation of a matrix like $\begin{bmatrix} 1 & 1\ 1 & 0\ \end{bmatrix}^{n}$ in the following.
Just like traditional power calculation, we can also use a loop and calculate the matrix exponentiation
WHAT YOU SHOULD DO (15 pts in total):
- Implement the function
naive_matrix_exp
(15 pts) inassign1.c
.
ATTENTION:
- NO GRADES will be given unless you implement the correct MATRIX EXPONENTIATION!
- Do the size checking in the function and show the result by return value. If the return value of your function is not 0, DO NOT modify the values in
mat_res
. - DO the modulo operation(
%MODULO
) during the calculation and be attention to the overflow! - REUSE the code you have implemented!
- It is GUARANTEED that
mat_res
is different frommat_a
. Be CAREFUL about the arguments you passed to the matrix multiplication!
Comparing the MATRIX EXPONENTIATION to the EXPONENTIATION of NUMBERS, if we can calculate the power of numbers by QUICK POWER, how can we use the same way to optimize the MATRIX EXPONENTIATION and reduce the comlexity of the calculation to
WHAT YOU SHOULD DO (15 pts in total):
- REVIEW the pseudo code of QUICK POWER.
- Think about how to optimize the MATRIX EXPONENTIATION?
- Implement the function
fast_matrix_exp
(15 pts) inassignment1.c
.
ATTENTION:
- NO GRADES will be given unless you implement the correct FAST MATRIX EXPONENTIATION!
- Do the size checking in the function and show the result by return value. If the return value of your function is not 0, DO NOT modify the values in
mat_res
. - DO the modulo operation(
%MODULO
) during the calculation and be attention to the overflow! - REUSE the code you have implemented!
- If you do not get full score in the Naive Matrix Exponentiation part but do in this part, you will eventually get full scores for both parts.
- It is GUARANTEED that
mat_res
is different frommat_a
. Be CAREFUL about the arguments you passed to the matrix multiplication! - Be AWARE of the type of parameter
exp
!
At the beginning of this section, we introduce the MATRIX EXPONENTIATION by Fibonacci Sequence. In this part, you are required to use the knowledge you obtain, to calculate the Fibonacci Sequence using Fast Matrix Exponentiation.
In our definition,
WHAT YOU SHOULD DO (20 pts in total):
- REVIEW the relationship between the RECURSIVE DERIVATION and MATRIX EXPONENTIATION.
- Implement the function
fast_cal_fib
(20 pts) inassign1.c
.
ATTENTION:
- NO GRADES will be given unless you implement the function with correct time complexity!
-
DO the modulo operation(
%MODULO
) during the calculation and be attention to the overflow! - REUSE the code you have implemented!
- It is guaranteed that the arguments are valid, i.e.,
$0 < n \le 10^{18}$ .
- Make sure to CREATE the source file
assign1.c
for your assignment. This file is in which you should implement all the required functions. - Make sure that you implement all the functions:
quick_power
,matrix_addition
,matrix_multiplication
,naive_matrix_exp
,fast_matrix_exp
,fast_cal_fib
. Even if you do not know how to finish several of them or there are some bugs, please IMPLEMENT them in source file as well! Or you may get ZERO for the whole code part in assignment.
Submit two files to Blackboard.
- assign1.c
- your assignment report, it needs not to be long, but should be able to explain the difficulties you encountered in completing the assignment and how you solve them. If you think there are highlights in your code, please point them out in the report. Both Chinese and English are allowed.
Our online judge (http://120.25.240.87/) provides you several public test cases.
Your user name is your student id, the initial password is 123456. (Please change your password ASAP)
If you have problems using the oj, you can contact the SA: He Zean (qq: 317576256, or find me in the group chat)
Public test cases and results are available at GitHub