# 機械学習で二次方程式の解 1

```a(x-α)(x-β)=0
```

a = 1 で固定し

(0,0)
(0,1)
...
(100,99)
(100,100)
101×101=10201通りを学習させてみました。
ニューラルネットワークはとりあえずこうしてみました。

ちゃんと書くのがめんどうなので

```        double[,] w0 = new double[,]{
{ 0.5,0.5,0.5},
{ 0.5,0.5,0.5},
{ 0.5,0.5,0.5},
{ 0.5,0.5,0.5}};

double[,] w1 = new double[,]{
{ 0.5,0.5},
{ 0.5,0.5},
{ 0.5,0.5},
{ 0.5,0.5}};

private void core()
{
for (double alpha = 0; alpha <= 100; alpha++)
{
for (double beta = 0; beta <= 100; beta++)
{
//
double a = 1;
double b = -(alpha + beta);
double c = alpha * beta;
double d = b * b - 4 * a * c;

//forward
double h0_0_in = a * w0[0, 0] + b * w0[1, 0] + c * w0[2, 0] + w0[3, 0];
double h0_1_in = a * w0[0, 1] + b * w0[1, 1] + c * w0[2, 1] + w0[3, 1];
double h0_2_in = a * w0[0, 2] + b * w0[1, 2] + c * w0[2, 2] + w0[3, 2];

double h0_0_out = s(h0_0_in);
double h0_1_out = s(h0_1_in);
double h0_2_out = s(h0_2_in);

double o_0_in = h0_0_out * w1[0, 0] + h0_1_out * w1[1, 0] + h0_2_out * w1[2, 0] + w1[3, 0];
double o_1_in = h0_0_out * w1[0, 1] + h0_1_out * w1[1, 1] + h0_2_out * w1[2, 1] + w1[3, 1];

double o_0_out = o_0_in;
double o_1_out = o_1_in;

double[] mE = new double[] { o_0_out - alpha, o_1_out - beta };

Invoke(new dldl(delegate
{
a.ToString(), b.ToString(), c.ToString(), d.ToString(),
alpha.ToString(), beta.ToString(),
w0[0, 0].ToString(), w0[0, 1].ToString(), w0[0, 2].ToString(),
w0[1, 0].ToString(), w0[1, 1].ToString(), w0[1, 2].ToString(),
w0[2, 0].ToString(), w0[2, 1].ToString(), w0[2, 2].ToString(),
w0[3, 0].ToString(), w0[3, 1].ToString(), w0[3, 2].ToString(),
h0_0_in.ToString(), h0_0_out.ToString(),
h0_1_in.ToString(), h0_1_out.ToString(),
h0_2_in.ToString(), h0_2_out.ToString(),
w1[0, 0].ToString(), w1[0, 1].ToString(),
w1[1, 0].ToString(), w1[1, 1].ToString(),
w1[2, 0].ToString(), w1[2, 1].ToString(),
w1[3, 0].ToString(), w1[3, 1].ToString(),
o_0_in.ToString(), o_0_out.ToString(),
o_1_in.ToString(), o_1_out.ToString(),
mE[0].ToString(), mE[1].ToString()
);
Refresh();
}));

//backward
w1[0, 0] = w1[0, 0] - ((-mE[0]) * h0_0_out);
w1[1, 0] = w1[1, 0] - ((-mE[0]) * h0_1_out);
w1[2, 0] = w1[2, 0] - ((-mE[0]) * h0_2_out);
w1[3, 0] = w1[3, 0] - -mE[0];

w1[0, 1] = w1[0, 1] - ((-mE[1]) * h0_0_out);
w1[1, 1] = w1[1, 1] - ((-mE[1]) * h0_1_out);
w1[2, 1] = w1[2, 1] - ((-mE[1]) * h0_2_out);
w1[3, 1] = w1[3, 1] - -mE[1];

w0[0, 0] = w0[0, 0] - (((-mE[0] * w1[0, 0]) + (-mE[1] * w1[0, 1])) * s(-h0_0_out) * (1 - s(-h0_0_out)) * a);
w0[0, 1] = w0[0, 1] - (((-mE[0] * w1[0, 0]) + (-mE[1] * w1[0, 1])) * s(-h0_1_out) * (1 - s(-h0_1_out)) * a);
w0[0, 2] = w0[0, 2] - (((-mE[0] * w1[0, 0]) + (-mE[1] * w1[0, 1])) * s(-h0_2_out) * (1 - s(-h0_2_out)) * a);

w0[1, 0] = w0[1, 0] - (((-mE[0] * w1[1, 0]) + (-mE[1] * w1[1, 1])) * s(-h0_0_out) * (1 - s(-h0_0_out)) * b);
w0[1, 1] = w0[1, 1] - (((-mE[0] * w1[1, 0]) + (-mE[1] * w1[1, 1])) * s(-h0_1_out) * (1 - s(-h0_1_out)) * b);
w0[1, 2] = w0[1, 2] - (((-mE[0] * w1[1, 0]) + (-mE[1] * w1[1, 1])) * s(-h0_2_out) * (1 - s(-h0_2_out)) * b);

w0[2, 0] = w0[2, 0] - (((-mE[0] * w1[2, 0]) + (-mE[1] * w1[2, 1])) * s(-h0_0_out) * (1 - s(-h0_0_out)) * c);
w0[2, 1] = w0[2, 1] - (((-mE[0] * w1[2, 0]) + (-mE[1] * w1[2, 1])) * s(-h0_1_out) * (1 - s(-h0_1_out)) * c);
w0[2, 2] = w0[2, 2] - (((-mE[0] * w1[2, 0]) + (-mE[1] * w1[2, 1])) * s(-h0_2_out) * (1 - s(-h0_2_out)) * c);

w0[3, 0] = w0[3, 0] - (((-mE[0] * w1[3, 0]) + (-mE[1] * w1[3, 1])) * s(-h0_0_out) * (1 - s(-h0_0_out)));
w0[3, 1] = w0[3, 1] - (((-mE[0] * w1[3, 0]) + (-mE[1] * w1[3, 1])) * s(-h0_1_out) * (1 - s(-h0_1_out)));
w0[3, 2] = w0[3, 2] - (((-mE[0] * w1[3, 0]) + (-mE[1] * w1[3, 1])) * s(-h0_2_out) * (1 - s(-h0_2_out)));
}
}

Invoke(new dldl(delegate
{
button1.Enabled = true;
}));
}

private double s(double x)
{
return 1.0/(1.0 + Math.Exp(-x));
}

private delegate void dldl();

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
//列ヘッダーかどうか調べる
if (e.ColumnIndex < 0 && e.RowIndex >= 0)
{
//セルを描画する
e.Paint(e.ClipBounds, DataGridViewPaintParts.All);

//行番号を描画する範囲を決定する
Rectangle indexRect = e.CellBounds;
indexRect.Inflate(-2, -2);
//行番号を描画する
TextRenderer.DrawText(e.Graphics,
(e.RowIndex + 1).ToString(),
e.CellStyle.Font,
indexRect,
e.CellStyle.ForeColor,
TextFormatFlags.Right | TextFormatFlags.VerticalCenter);
//描画が完了したことを知らせる
e.Handled = true;
}
}

private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;