Our first M-file computes the value of a machine number.
Let us choose fl1 as name of function and of course as name of the file also. We give a vector as input parameter. The last coordinate of vector gives the characteristic of machine number (in tenary numeral system). We store the signed mantissa in the other coordinates.
The output argument be the real number what is represented by our machine number.
The first bit of mantissa we can use for storing the sign of the number. (Originally this bit is surely 1.) When the number is positive, then the signbit be 0, in case of negative numbers we use 1 as first bit.
We don’t have to know the parameters of machine number set for converting the number. The length of mantissa can be read from input data. And we assume that the bounds of characteristic are such that our carachteristic be allowed.
Before starting computation let us check whether the given data can be a machine number or not. (All but last coordinates are from set {0,1} and last is an integer.)
% 判断 最后一位是整数 if ~isaninteger(vector(end)) % 如果不是,将返回值标记为无效 dec = nan; return end
% 对数组内容进行验证,起始 到 倒数第二位 for n = vector(1:end-1) % 只能是二进制 if ~(n == 0 || n == 1) dec = nan; return end end
% 初始化赋值 dec = 0; % 从 第二位 到 倒数第二位 for n = 2:length(vector)-1 if vector(n) == 1 % 二进制转十进制算法 dec = dec + 1/(2^(n-1)); end end
% 位移,应用指数位 dec = dec * 2^vector(end);
% 检查正负号 if vector(1) dec = -dec; return end end
在数轴上展示机器数
Let us write anothe M-file, called fl2. It displays the elements of a given machine number set on the real axis. Compute the number of elements and the following parameters: M∞, ε0, ε1. (They will be the output arguments of the function)
The function waits 3 (integer) number as input. They are the parameters of the set: t, k1, k2.
Let us check whether the input parameters are appropriate. (t ∈ N+ and k1, k2 ∈ Z, and of course k1 < k2)
For the computation we can call our first function (fl1)
The set is symmetric. We can use this property for the faster computation.
% 最大位数必须大于零 且 是整数 % 低指数 小于或者等于 高指数,同时是整数 if ~(digits > 0 && isaninteger(digits)) ... || bottomExp > topExp ... || ~isaninteger(bottomExp) ... || ~isaninteger(topExp) max = nan; return end
mn = []; % 遍历出全部位数的机器数可能性 % n 从 1 开始枚举 到 最大位数 for n = 1:digits % 括号里面是十进制数组,长度为 2^n % 如 [0, 1, 2, 3],-1 的原因是从 0 开始 % de2bi 会把数组里面的每一个数都转换成二进制 % 矩阵 m 有 2^n 行 n 列 % 这样写的好处是写起来简单,问题是会产生大量重复内容 m = de2bi(0:(2^n)-1);
% 按行遍历矩阵,取出每一个二进制结果 for k = 1:size(m, 1) % 遍历所有的指数大小可能性,同样会产生大量重复内容 for e = bottomExp:topExp % 把二进制结果转换为机器数,并储存 % 这种持续变换矩阵大小的行为效率低下,但是写起来简单 mn = [mn, fl1([0, m(k, :), e])]; end end end
% 将所有重复项排除,此方法会自动从小到大排序 mn = unique(mn); max = mn(end); min = mn(1);
% 对称 mn = [-mn, mn]; if draw plot(mn, repelem(0, length(mn)), "o") end end
十进制转机器数
The third function finds the machine number what representates the given real number.
The name be fl3. The function waits the real number and parameters of set of machine numbers (t, k1, k2.) as input. And gives back a vector with t+1 coordinates. The last coordinate be the characteristic and the firs t stores the signed mantissa. (As in case of input argument of function fl1).
The first bit of mantissa is the sign-bit as in exercise 1. The value of sign is 0 when number is positive and 1 when it is negative.
Check the input arguments whether they are appropriate. And the real number whether can representate in machine number set. (ε0 ≤ |r| ≤ M∞)
if power % 强行截断超出部分,只留超出的第一位,进行舍零入一 bin = bin(1:digits + 1); end
% 是否需要进位 over = 0; % 只有当整数向后位移的情况才可能超出 if power over = bin(end); end
% 逆向遍历数组 for n = digits:-1:1 if over % 是 1 则变成 0,继续进位 if bin(n) bin(n) = 0; else % 如果是 0 则 停止进位 bin(n) = 1; over = 0; end else break end end
% 我们不需要考虑溢出的情况,因为最开始就已经检查过范围了 vector = [sgn, bin(1:digits), power]; end
机器数相加
Let us write a function for addition between machine numbers.
Let us call the file to fl4. It waits for two vectors as input. (They are representate the machine numbers as before). The output be a vector with the machine number of the sum.
Use machine-addition. The double conversion is not acceptable. (To compute the real numbers belongs to inputs, summing them and reconverting to machin number is not allowed.)
Check the inputs. (They have to have same length and have to be machine numbers)
If one of the numbers is negative (the first bit is 1) then in real the operation is a substraction.
% Gauss-Jordan r = 1; for c = 1:cols % 找出当前列中,绝对值最大的数字,及其所在的行 % 使用部分主元消去法可减少(但会不消除)计算中的舍入误差 % 主元位置:行中最左边的非零元素 [num, target] = max(abs(M(r:end, c))); % 加上 r 的原因是因为上面 max 判断的是被截断的矩阵 target = r + target - 1;
if (num <= tolerance) % 跳过当前列,将近似零的项直接变成零 % 这可以防止使用小于容差的非零主元元素进行运算 M(r:end, c) = zeros(rows - r + 1, 1); if display disp(M) end else % 交换最大行与当前行 M([target, r], c:end) = M([r, target], c:end); if display disp(M) end
% 标准化最大行(把主元变成1) M(r, c:end) = M(r, c:end) / M(r, c); if display disp(M) end
% 消除当前的列(消元),但是要除开当前行 erow = [1:r - 1, r + 1:rows]; M(erow, c:end) = M(erow, c:end) - M(erow, c) * M(r, c:cols); if display disp(M) end
% 检查是否完成行遍历 if (r == rows) break; end
r = r + 1; end end
x = M(:, end); end
Whole Pivoting
Extend the previous m-file (but save as a new name for example gaussel2) with steps of partial and whole pivoting method.
Using partial or whole pivoting could be choosen by user (for example according to a boolean input parameter), but if the partial pivoting is stucked then automatically switch to whole pivoting method. If we used whole pivoting despite user has choosen partial pivoting, then inform user about the switch
Give an opportunity for displaying matrices A(i) during computation. Don’t forget that pivoting method can be changed the matrix so we have to display it after row and coloumn swap.
Don’t forget that the pivoting method can be changed the solution.
% Whole Pivoting r = 1; for c = 1:cols - 1 % 找出行列最大值 [maxc, rowI] = max(abs(M(r:end, c:end - 1))); [num, colI] = max(maxc); row = rowI(colI) + c - 1; col = colI + c - 1;
if (num <= tolerance) M(r:end, c) = zeros(rows - r + 1, 1); if display disp(M) end else % 交换列 M(r:end, [col, c]) = M(r:end, [c, col]); if display disp(M) end
% 交换行 M([row, r], c:end) = M([r, row], c:end); if display disp(M) end
% 标准化 M(r, c:end) = M(r, c:end) / M(r, c); if display disp(M) end
% 消元 erow = [1:r - 1, r + 1:rows]; M(erow, c:end) = M(erow, c:end) - M(erow, c) * M(r, c:cols); if display disp(M) end
if (r == rows) break; end
r = r + 1; end end
% 调换回正常顺序 x = M(xOrd, end); end
求逆矩阵
Apply Gaussian elimantion for computing inverse of an square matrix. The name of function: gaussel3
Check input argument(s) before computing
Compute the determinant of matrix. If you have written the function gaussel1 such that it accepts multiple right-sides, then you can call it during computation.
if (m ~= n) error("A should be a square matix") end
if (rank(A) ~= size(A, 2)) % 加了这个 magic 就过不了了 warning("the columns of A have to be linear independent") end
Q = zeros(m); R = zeros(m);
% 从最左侧的列向量向右 for col = 1:n a = A(:, col); q = a;
% 减去 A 中当前列向量在之前已找到的基向量上的投影分量 for b = 1:col-1 % 计算给定列向量a在已处理的基向量Q的第b列上的投影分量 r = Q(:, b)' * a; % 减去当前列向量在之前处理的基向量上的投影分量 q = q - r * Q(:, b); % 记录对应 R 矩阵中的元素值 R(b, col) = r; end
% 对当前基向量进行正交化 q = q / norm(q);
% 更新结果 Q(:, col) = q; R(col, col) = a' * q; end
end
Householder
Write an M-file to give the matrix of a Householder transformation, from a known point and its image. The name of function let be: householder
Input parameters: the coordinatas of the point and its image (P, P’) Point P (and ofcourse P’ also) can be from Rn where n is not predetermined.
Output argument: the matrix of Householder-transformation
Take care of choosing sign during transformation (the parameter σ effects the stability of the method)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
% 3. Householder 变换主要就是那个公式,没有什么别的 functionH = householder(P, Prem) arguments P (:,1) Prem (:,1) % P' end % 解题参考 NumSampleTest1SolutionsP1 213
if (size(P) ~= size(Prem)) error("Size P not equal to Size ImgP") end
u = P - Prem; v = u / norm(u);
% H(v) = I - 2 * v * v' H = eye(size(P, 1)) - 2 * (v * v'); end
点映射
The third function will asking data via graphical input. (It works for 2D points) Display points and the hyperspace of reflection. Ask for another point (also via graphical input) and apply the transformation to the new point. The function householder can be called during the algorithm. the name of function: hhgraph
syms x y u; % 圆的标准方程 c = x ^ 2 + y ^ 2 - R ^ 2; % 计算点 (x,y) 到第二个点(PointX2,PointY2)之间的欧几里得距离 d = (x - PointX2) ^ 2 + (y - PointY2) ^ 2; % 求出第二个点(PointX2,PointY2)在反射变换后的位置,以确定反射变换矩阵 H h = d + u * c;
% 前两个参数表示 h 关于 x 和 y 的一阶导数,它们用来求解 h 关于 x 和 y 的根 % 这些根是 h 关于 x 和 y 的极值点,它们决定了反射变换后第二个点的位置 % 第三个参数表示 h 关于 u 的一阶导数,它用来求解 h 关于 u 的根 % 这个根是 h 关于 u 的极值点,它决定了反射变换矩阵 H 的值 res = solve(diff(h, x) == 0, diff(h, y) == 0, diff(h, u) == 0); x = res.x; y = res.y;
% 4. 用 Gauss Seidel 迭代法解线性方程组 Ax=b % A为方程组的系数矩阵 % b为方程组的右端项 %epsilon:近似解的误差 %Max:迭代的最大次数 functionx = gaussseid(A, b, epsilon, Max) arguments A b (:,1) epsilon (1,1) = 1e-5 Max (1,1) = 1000 end
[row, col] = size(A); bRow = length(b);
%当方程组行与列的维数不相等 if row ~= col error('The rows and columns of matrix A must be equal'); end
% 当方程组与右端项的维数不匹配 if col ~= bRow error('The columns of A must be equal the length of b'); end
%迭代初始值 x = zeros(bRow, 1); %diag(A)是取出对角元的向量,对该向量再作用diag()函数表示以该对角元向量生成对角矩阵 D = diag(diag(A)); %将矩阵分裂为A=D-L-U %下三角 L = -tril(A, -1); %上三角 U = -triu(A, 1);
%G-S迭代法的迭代公式 Xk+1 = (D-L)^(-1) * U * Xk + (D - L)^(-1) * b B = (D-L) \ U; g = (D-L) \ b;
%开始迭代Xk+1 = B * x + g %最大迭代次数 for k=1:Max %计算Xk+1用y存放 y=B*x + g;
%相邻两次迭代之间相差小于阈值 if norm(x-y) < epsilon break; end
%存放单步结果用于判断收敛 x = y; end end
Iterative solution of non-linear equations, Interpolation
二分法
Write an m-file for bisection method and call the file: bisect
Input arguments: the function f (we want to find one of the zeros). Give it as a string (the variable can be denoted by x or we can give the notation as another parameter. We will need the ends of the starting interval (a, b), the number of steps (n).
Output arguments: the appropriate approximation of root: x^∗ and the error estimation ε.
Before start we have to check the interval (is there a root inside?)
Write an m-file to find the generalised inverse of a given matrix. The name of file: geninv
Input argument: the matrix (A).
Output argument: The generalised inverse (A+)
Use the rank factorisation if the matrix is not fullranked. For the matrix operations we can use the included functions of Matlab (eg.: rank, inv, instead of solving LES we can use the command G=F\A, etc.)