二次型与矩阵对应关系

f(x)=a11x12+a22x22++annxn2+2a12x1x2+2a13x1x3++2an1,nxn1xn 观察各个项,行和列按x1,x2,x3,,xnx_1,x_2,x_3,\cdots,x_n的顺序排列成表格,每个格子内为行列相乘的项,平方项恰在对角线位置,其他项放在对角线上三角区域,可以得到下面方阵: x1x2x3xnx1a11x122a12x1x22a13x1x32a1nx1xnx20a22x222a23x2x32a2nx2xnx300a33x322a3nx3xnxn000annxn2 如果把像 2a12,2a13,,2a(n1)n2a_{12} , 2a_{13},\dots,2a_{(n-1)n} 这样的2倍的系数沿着对角线对称的位置拆分放置,即a12=a21,a13=a31,,a(n1)n=an(n1)a_{12}=a_{21} , a_{13}=a_{31},\dots,a_{(n-1)n}=a_{n(n-1)},那么可以得到下面的样子:

继续阅读“二次型与矩阵对应关系”

矩阵对角化

一、什么样的n阶矩阵才能对角化?

先说结论 {a.特征值无重根b.有重根{b.1.厄米特矩阵(Hermitian),特别的对称实数矩阵b.2.非厄矩阵{b.2.1.几何重数=代数重数b.2.2.几何重数≠代数重数

定理1:

λ1,λ2,,λm\lambda_1,\lambda_2,\dots,\lambda_m 是方阵AA的m个特征值,p1,p2,,pmp_1,p_2,\dots,p_m依次是与之对应的特征向量,如果λ1,λ2,,λm\lambda_1,\lambda_2,\dots,\lambda_m各不相等,则p1,p2,,pmp_1,p_2,\dots,p_m线性无关。

继续阅读“矩阵对角化”

韦达公式推导

一元n次方程 anxn+an1xn1+...+a1x+a0=0 \begin{align} a_nx^n + a_{n-1}x^{n-1} + … + a_1x + a_0 = 0 \end{align} 的根为x1,x2,...,xnx_1, x_2, …, x_n,其中an0a_n \neq 0。 那么(1)式可以写成下面的形式: an(xx1)(xx2)...(xxn)=0 \begin{align} a_n(x – x_1)(x – x_2)…(x – x_n) = 0 \end{align}

将其展开,并观察多项式系数,xn1x_{n-1}的系数: (x1+x2+...+xn)an-(x_1 + x_2 + … + x_n)a_n 常数项: (1)nx1x2...xn1an(-1)^nx_1x_2…x_{n-1}a_n

比较常数项和xn1x_{n-1}的系数,可以得到: a0=(1)nx1x2...xn1anan1=(x1+x2+...+xn)an \begin{aligned} a_0 &=(-1)^nx_1x_2…x_{n-1}a_n \\ a_{n-1} &=-(x_1 + x_2 + … + x_n)a_n \end{aligned}

\therefore i=1nxi=x1x2...xn1an=(1)na0ani=1nxi=x1+x2+...+xn=an1an \begin{equation} \begin{aligned} &\prod_{i=1}^nx_i=x_1x_2…x_{n-1}a_n=\frac{(-1)^{n}{a_0}}{a_n} \\ &\sum_{i=1}^nx_i=x_1 + x_2 + … + x_n = -\frac{a_{n-1}}{a_n} \end{aligned} \end{equation}

这就是一元n次方程的韦达公式。

直线与平面的向量表示

在初中我们就学过很多种直线的表示

一般式Ax+By+C=0Ax+By+C=0 A,BA,B不能同时为零;
斜截式y=kx+by = kx + b ,其中 kk 是斜率(slope),表示直线与x轴正方向夹角的正切值,bb 是纵截距(y-intercept,截距可以是负值),表示直线与y轴的交点的纵坐标;
点斜率yy1=k(xx1)y – y_{1} = k(x – x_{1}),其中 (x1,y1)(x_{1},y_{1}) 表示直线上一点, kk表示直线斜率;
截距式xa+yb=1\frac{x}{a} + \frac{y}{b} = 1,其中 a,ba,b分别表示直线与x轴和y轴的截距,也就是与x轴交点的横坐标和与y轴交点的纵坐标;
两点式xx1x2x1=yy1y2y1\frac{x – x_{1}}{x_{2} – x_{1}} = \frac{y – y_{1}}{y_{2} – y_{1}},其中 (x1,y1),(x2,y2)(x_{1},y_{1}),(x_{2},y_{2}) 表示直线上两点坐标;

继续阅读“直线与平面的向量表示”

如何:使用颜色矩阵对单色进行变换

GDI+ 提供用于存储和操作图像的 ImageBitmap 类。 ImageBitmap 对象用一个 32 位数字存储每个像素的颜色:红、绿、蓝和 Alpha 各 8 位。 这四个分量的值都是 0 到 255,其中 0 表示没有亮度,255 表示最大亮度。 alpha 分量指定颜色的透明度:0 表示完全透明,255 表示完全不透明。

颜色矢量采用 4 元组形式(红色、绿色、蓝色、alpha)。 例如,颜色矢量 (0, 255, 0, 255) 表示一种没有红色和蓝色但绿色达到最大亮度的不透明颜色。

表示颜色的另一种惯例是用数字 1 表示亮度达到最大。 通过使用这种约定,上一段中描述的颜色将可以由矢量 (0, 1, 0, 1) 表示。 在执行颜色变换时,GDI+ 遵循使用 1 为最大亮度的惯例。

可通过用 4×4 矩阵乘以这些颜色矢量将线性变换(旋转和缩放等)应用到颜色矢量中。 但是,您不能使用 4×4 矩阵进行平移(非线性)。 如果在每个颜色矢量中再添加一个虚拟的第 5 坐标(例如,数字 1),则可使用 5×5 矩阵应用任何组合形式的线性变换和平移。 由线性变换组成的后跟平移的变换称为仿射变换。

例如,假设您希望从颜色 (0.2, 0.0, 0.4, 1.0) 开始并应用下面的变换:

  1. 将红色分量乘以 2。
  2. 将 0.2 添加到红色、绿色和蓝色分量中。

下面的矩阵乘法将按照列出的顺序进行这对变换。

颜色矩阵的元素按照先行后列(从 0 开始)的顺序进行索引。 例如,矩阵 M 的第五行第三列由 M[4][2] 表示。

5×5 单位矩阵(在下面的插图中显示)在对角线上为 1,在其他任何地方为 0。 如果用单位矩阵乘以颜色矢量,则颜色矢量不会发生改变。 形成颜色变换矩阵的一种简便方法是从单位矩阵开始,然后进行较小的改动以产生所需的变换。

有关矩阵和变换的更详细的讨论,请参见坐标系统和变形

示例

下面的示例采用一个使用一种颜色 (0.2, 0.0, 0.4, 1.0) 的图像,并应用上一段中描述的变换。

下面的插图在左侧显示原来的图像,在右侧显示变换后的图像。

下面示例中的代码使用以下步骤进行重新着色:

  1. 初始化 ColorMatrix 对象。
  2. 创建一个 ImageAttributes 对象,并将 ColorMatrix 对象传递给 ImageAttributes 对象的 SetColorMatrix 方法。
  3. ImageAttributes 对象传递给 Graphics 对象的 DrawImage 方法。

C#

VB

Image image = new Bitmap(“InputColor.bmp”);
ImageAttributes imageAttributes = new ImageAttributes();
int width = image.Width;
int height = image.Height;

float[][] colorMatrixElements = {
   new float[] {2,  0,  0,  0, 0},        // red scaling factor of 2
   new float[] {0,  1,  0,  0, 0},        // green scaling factor of 1
   new float[] {0,  0,  1,  0, 0},        // blue scaling factor of 1
   new float[] {0,  0,  0,  1, 0},        // alpha scaling factor of 1
   new float[] {.2f, .2f, .2f, 0, 1}};    // three translations of 0.2

ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

imageAttributes.SetColorMatrix(
   colorMatrix,
   ColorMatrixFlag.Default,
   ColorAdjustType.Bitmap);

e.Graphics.DrawImage(image, 10, 10);

e.Graphics.DrawImage(
   image,
   new Rectangle(120, 10, width, height),  // destination rectangle
   0, 0,        // upper-left corner of source rectangle
   width,       // width of source rectangle
   height,      // height of source rectangle
   GraphicsUnit.Pixel,
   imageAttributes);

编译代码

前面的示例是为使用 Windows 窗体而设计的,它需要 Paint 事件处理程序的参数 PaintEventArgse

矩阵如何:修剪颜色

剪切是指按照与另一种颜色分量成比例的量来增加或减少颜色分量。 例如,考虑这样一种变换,将红色分量增加蓝色分量值的一半。 在这样的变换下,(0.2, 0.5, 1) 颜色将变成 (0.7, 0.5, 1)。 新的颜色分量是 0.2 + (1/2)(1) = 0.7。

示例

下面的示例从文件 ColorBars4.bmp 构造一个 Image 对象。 然后,该代码将上一段中描述的剪切变换应用到图像中的每个像素。

下面的插图在左侧显示原来的图像,在右侧显示剪切后的图像。

下表列出在剪切变换前后,四栏的颜色矢量。

Original剪切后
(0, 0, 1, 1)(0.5, 0, 1, 1)
(0.5, 1, 0.5, 1)(0.75, 1, 0.5, 1)
(1, 1, 0, 1)(1, 1, 0, 1)
(0.4, 0.4, 0.4, 1)(0.6, 0.4, 0.4, 1)

VB

Image image = new Bitmap(“ColorBars.bmp”);
ImageAttributes imageAttributes = new ImageAttributes();
int width = image.Width;
int height = image.Height;

float[][] colorMatrixElements = {
        new float[] {1,  0,  0,  0, 0},
        new float[] {0,  1,  0,  0, 0},
        new float[] {0.5f,  0,  1,  0, 0},
        new float[] {0,  0,  0,  1, 0},
        new float[] {0, 0, 0, 0, 1}};

ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

imageAttributes.SetColorMatrix(
   colorMatrix,
   ColorMatrixFlag.Default,
   ColorAdjustType.Bitmap);

e.Graphics.DrawImage(image, 10, 10, width, height);

e.Graphics.DrawImage(
   image,
   new Rectangle(150, 10, width, height),  // destination rectangle
    0, 0,        // upper-left corner of source rectangle
    width,       // width of source rectangle
    height,      // height of source rectangle
    GraphicsUnit.Pixel,
   imageAttributes);

编译代码

前面的示例是为使用 Windows 窗体而设计的,它需要 Paint 事件处理程序的参数 PaintEventArgse。 用系统上有效的图像名称和路径替换 ColorBars.bmp

矩阵全局变换和局部变换

全局变换是应用于由给定的 Graphics 对象绘制的每个项目的变换。 与此相反,局部变换则是应用于要绘制的特定项目的变换。

全局变换

若要创建全局变换,请构造 Graphics 对象,再操作其 Transform 属性。 Transform 属性是 Matrix 对象,因此,它能够保存仿射变换的任何序列。 存储在 Transform 属性中的变换被称为世界变换。 Graphics 类提供了几个构建复合世界变换的方法:MultiplyTransformRotateTransformScaleTransformTranslateTransform。 下面的示例绘制了两次椭圆:一次在创建世界变换之前,一次在创建世界变换之后。 变换首先在 y 方向上缩放 0.5 倍,再在 x 方向平移 50 个单位,然后旋转 30 度。

C#

VB

myGraphics.DrawEllipse(myPen, 0, 0, 100, 50);
myGraphics.ScaleTransform(1, 0.5f);
myGraphics.TranslateTransform(50, 0, MatrixOrder.Append);
myGraphics.RotateTransform(30, MatrixOrder.Append);
myGraphics.DrawEllipse(myPen, 0, 0, 100, 50);

下图显示了变换中涉及的矩阵。

System_CAPS_note 注意
在前面的示例中,椭圆围绕坐标系的原点旋转。原点位于工作区的左上角。 与椭圆围绕其自身中心旋转相比,这样会产生不同的结果。

局部变换

局部变换应用于要绘制的特定项目。 例如,GraphicsPath 对象具有 Transform 方法,可用来对该路径的数据点进行变换。 下面的示例绘制了一个没有变换的矩形以及一个有旋转变换的路径。 (假定没有世界变换)。

C#

VB

Matrix myMatrix = new Matrix();
myMatrix.Rotate(45);
myGraphicsPath.Transform(myMatrix);
myGraphics.DrawRectangle(myPen, 10, 10, 100, 50);
myGraphics.DrawPath(myPen, myGraphicsPath);

世界变换可与局部变换合并,以得到多种结果。 例如,世界变换可用于修正坐标系统,而局部变换可用于旋转和缩放在新坐标系统上绘制的对象。

假定您需要原点距工作区左边缘 200 像素、距工作区顶部 150 像素的坐标系统。 此外,假定您需要的度量单位是像素,且 x 轴指向右方,y 轴指向上方。 默认的坐标系统是 y 轴指向下方,因此您需要执行绕水平坐标轴的反射。 下图显示了这样的矩阵反射。

下一步,假定您需要执行一个向右 200 个单位、向下 150 个单位的平移。

下面的示例通过设置 Graphics 对象的世界变换,建立前面刚刚描述过的坐标系统。

C#

VB

Matrix myMatrix = new Matrix(1, 0, 0, -1, 0, 0);
myGraphics.Transform = myMatrix;
myGraphics.TranslateTransform(200, 150, MatrixOrder.Append);

下面的代码(置于前面示例的结尾处)创建了由一个单独矩形组成的路径,该矩形的左下角在新坐标系统的原点。 矩形经过两次填充:一次不使用局部变换,一次使用局部变换。 局部变换包括在水平方向上缩放 2 倍,然后再旋转 30 度。

C#

VB

// Create the path.
GraphicsPath myGraphicsPath = new GraphicsPath();
Rectangle myRectangle = new Rectangle(0, 0, 60, 60);
myGraphicsPath.AddRectangle(myRectangle);

// Fill the path on the new coordinate system.
// No local transformation
myGraphics.FillPath(mySolidBrush1, myGraphicsPath);

// Set the local transformation of the GraphicsPath object.
Matrix myPathMatrix = new Matrix();
myPathMatrix.Scale(2, 1);
myPathMatrix.Rotate(30, MatrixOrder.Append);
myGraphicsPath.Transform(myPathMatrix);

// Fill the transformed path on the new coordinate system.
myGraphics.FillPath(mySolidBrush2, myGraphicsPath);

下图显示了新的坐标系统和两个矩形。

腾讯云图