#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define ROWS 29
#define COLS 5
// Function to multiply two matrices
void matrix_multiply(double a[ROWS][COLS], double b[COLS][ROWS], double result[COLS][COLS]) {
for (int i = 0; i < COLS; ++i) {
for (int j = 0; j < COLS; ++j) {
result[i][j] = 0;
for (int k = 0; k < ROWS; ++k) {
result[i][j] += a[k][i] * b[j][k];
}
}
}
}
// Function to transpose a matrix
void matrix_transpose(double src[ROWS][COLS], double dest[COLS][ROWS]) {
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLS; ++j) {
dest[j][i] = src[i][j];
}
}
}
// Function to invert a 5x5 matrix (using Gauss-Jordan elimination)
int matrix_inverse(double src[COLS][COLS], double dest[COLS][COLS]) {
int i, j, k;
double ratio;
double aug[COLS][2 * COLS];
// Initialize augmented matrix
for (i = 0; i < COLS; i++) {
for (j = 0; j < COLS; j++) {
aug[i][j] = src[i][j];
aug[i][j + COLS] = (i == j) ? 1 : 0;
}
}
// Apply Gauss-Jordan elimination
for (i = 0; i < COLS; i++) {
if (aug[i][i] == 0) {
// Find a row below the current row with a non-zero element in the current column
for (k = i + 1; k < COLS; k++) {
if (aug[k][i] != 0) {
for (j = 0; j < 2 * COLS; j++) {
double temp = aug[i][j];
aug[i][j] = aug[k][j];
aug[k][j] = temp;
}
break;
}
}
}
// Make the diagonal contain all ones
for (j = 0; j < COLS; j++) {
aug[i][j] /= aug[i][i];
aug[i][j + COLS] /= aug[i][i];
}
// Make the other rows contain zeros in the current column
for (k = 0; k < COLS; k++) {
if (k != i) {
ratio = aug[k][i];
for (j = 0; j < 2 * COLS; j++) {
aug[k][j] -= ratio * aug[i][j];
}
}
}
}
// Copy the inverse matrix
for (i = 0; i < COLS; i++) {
for (j = 0; j < COLS; j++) {
dest[i][j] = aug[i][j + COLS];
}
}
return 0;
}
// Function to solve the linear system W = inv(X^T * X) * X^T * y
void matrix_vector_multiply(double matrix[COLS][COLS], double vector[COLS], double result[COLS]) {
for (int i = 0; i < COLS; ++i) {
result[i] = 0;
for (int j = 0; j < COLS; ++j) {
result[i] += matrix[i][j] * vector[j];
}
}
}
int main() {
// Provided dataset
double data[ROWS][3] = {
{3.85, 3.8, 7.38}, {3.75, 4, 8.51}, {3.7, 4.3, 9.52}, {3.7, 3.7, 7.5}, {3.6, 3.85, 9.33},
{3.6, 3.8, 8.28}, {3.6, 3.75, 8.75}, {3.8, 3.85, 7.87}, {3.8, 3.65, 7.1}, {3.85, 4, 8},
{3.9, 4.1, 7.89}, {3.9, 4, 8.15}, {3.7, 4.1, 9.1}, {3.75, 4.2, 8.86}, {3.75, 4.1, 8.9},
{3.8, 4.1, 8.87}, {3.7, 4.3, 9}, {3.7, 4.1, 8.75}, {3.8, 3.75, 7.95}, {3.8, 3.75, 7.65},
{3.75, 3.65, 7.27}, {3.7, 3.9, 8}, {3.55, 3.65, 8.5}, {3.6, 4.1, 8.75}, {3.65, 4.25, 9.21},
{3.7, 3.65, 8.27}, {3.75, 3.75, 7.67}, {3.8, 3.85, 7.93}, {3.7, 4.25, 9.26}
};
// Initialize matrices
double X[ROWS][COLS];
double Xt[COLS][ROWS];
double XtX[COLS][COLS];
double XtX_inv[COLS][COLS];
double y[ROWS];
double Xty[COLS];
double W[COLS];
// Populate matrices X and vector y
for (int i = 0; i < ROWS; ++i) {
X[i][0] = 1.0; // First column of ones
X[i][1] = data[i][0]; // x1 column
X[i][2] = data[i][1]; // x2 column
X[i][3] = data[i][0] * data[i][0]; // x1^2 column
X[i][4] = data[i][1] * data[i][1]; // x2^2 column
y[i] = data[i][2];
}
// Transpose of X
matrix_transpose(X, Xt);
// Xt * X
matrix_multiply(Xt, X, XtX);
// Inverse of Xt * X
matrix_inverse(XtX, XtX_inv);
// Xt * y
matrix_vector_multiply(Xt, y, Xty);
// W = inv(XtX) * Xty
matrix_vector_multiply(XtX_inv, Xty, W);
// Print the result
for (int i = 0; i < COLS; ++i) {
}
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPG1hdGguaD4KCiNkZWZpbmUgUk9XUyAyOQojZGVmaW5lIENPTFMgNQoKLy8gRnVuY3Rpb24gdG8gbXVsdGlwbHkgdHdvIG1hdHJpY2VzCnZvaWQgbWF0cml4X211bHRpcGx5KGRvdWJsZSBhW1JPV1NdW0NPTFNdLCBkb3VibGUgYltDT0xTXVtST1dTXSwgZG91YmxlIHJlc3VsdFtDT0xTXVtDT0xTXSkgewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBDT0xTOyArK2kpIHsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IENPTFM7ICsraikgewogICAgICAgICAgICByZXN1bHRbaV1bal0gPSAwOwogICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IFJPV1M7ICsraykgewogICAgICAgICAgICAgICAgcmVzdWx0W2ldW2pdICs9IGFba11baV0gKiBiW2pdW2tdOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgovLyBGdW5jdGlvbiB0byB0cmFuc3Bvc2UgYSBtYXRyaXgKdm9pZCBtYXRyaXhfdHJhbnNwb3NlKGRvdWJsZSBzcmNbUk9XU11bQ09MU10sIGRvdWJsZSBkZXN0W0NPTFNdW1JPV1NdKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IFJPV1M7ICsraSkgewogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgQ09MUzsgKytqKSB7CiAgICAgICAgICAgIGRlc3Rbal1baV0gPSBzcmNbaV1bal07CiAgICAgICAgfQogICAgfQp9CgovLyBGdW5jdGlvbiB0byBpbnZlcnQgYSA1eDUgbWF0cml4ICh1c2luZyBHYXVzcy1Kb3JkYW4gZWxpbWluYXRpb24pCmludCBtYXRyaXhfaW52ZXJzZShkb3VibGUgc3JjW0NPTFNdW0NPTFNdLCBkb3VibGUgZGVzdFtDT0xTXVtDT0xTXSkgewogICAgaW50IGksIGosIGs7CiAgICBkb3VibGUgcmF0aW87CiAgICBkb3VibGUgYXVnW0NPTFNdWzIgKiBDT0xTXTsKCiAgICAvLyBJbml0aWFsaXplIGF1Z21lbnRlZCBtYXRyaXgKICAgIGZvciAoaSA9IDA7IGkgPCBDT0xTOyBpKyspIHsKICAgICAgICBmb3IgKGogPSAwOyBqIDwgQ09MUzsgaisrKSB7CiAgICAgICAgICAgIGF1Z1tpXVtqXSA9IHNyY1tpXVtqXTsKICAgICAgICAgICAgYXVnW2ldW2ogKyBDT0xTXSA9IChpID09IGopID8gMSA6IDA7CiAgICAgICAgfQogICAgfQoKICAgIC8vIEFwcGx5IEdhdXNzLUpvcmRhbiBlbGltaW5hdGlvbgogICAgZm9yIChpID0gMDsgaSA8IENPTFM7IGkrKykgewogICAgICAgIGlmIChhdWdbaV1baV0gPT0gMCkgewogICAgICAgICAgICAvLyBGaW5kIGEgcm93IGJlbG93IHRoZSBjdXJyZW50IHJvdyB3aXRoIGEgbm9uLXplcm8gZWxlbWVudCBpbiB0aGUgY3VycmVudCBjb2x1bW4KICAgICAgICAgICAgZm9yIChrID0gaSArIDE7IGsgPCBDT0xTOyBrKyspIHsKICAgICAgICAgICAgICAgIGlmIChhdWdba11baV0gIT0gMCkgewogICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCAyICogQ09MUzsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSB0ZW1wID0gYXVnW2ldW2pdOwogICAgICAgICAgICAgICAgICAgICAgICBhdWdbaV1bal0gPSBhdWdba11bal07CiAgICAgICAgICAgICAgICAgICAgICAgIGF1Z1trXVtqXSA9IHRlbXA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBNYWtlIHRoZSBkaWFnb25hbCBjb250YWluIGFsbCBvbmVzCiAgICAgICAgZm9yIChqID0gMDsgaiA8IENPTFM7IGorKykgewogICAgICAgICAgICBhdWdbaV1bal0gLz0gYXVnW2ldW2ldOwogICAgICAgICAgICBhdWdbaV1baiArIENPTFNdIC89IGF1Z1tpXVtpXTsKICAgICAgICB9CgogICAgICAgIC8vIE1ha2UgdGhlIG90aGVyIHJvd3MgY29udGFpbiB6ZXJvcyBpbiB0aGUgY3VycmVudCBjb2x1bW4KICAgICAgICBmb3IgKGsgPSAwOyBrIDwgQ09MUzsgaysrKSB7CiAgICAgICAgICAgIGlmIChrICE9IGkpIHsKICAgICAgICAgICAgICAgIHJhdGlvID0gYXVnW2tdW2ldOwogICAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IDIgKiBDT0xTOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBhdWdba11bal0gLT0gcmF0aW8gKiBhdWdbaV1bal07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gQ29weSB0aGUgaW52ZXJzZSBtYXRyaXgKICAgIGZvciAoaSA9IDA7IGkgPCBDT0xTOyBpKyspIHsKICAgICAgICBmb3IgKGogPSAwOyBqIDwgQ09MUzsgaisrKSB7CiAgICAgICAgICAgIGRlc3RbaV1bal0gPSBhdWdbaV1baiArIENPTFNdOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gMDsKfQoKLy8gRnVuY3Rpb24gdG8gc29sdmUgdGhlIGxpbmVhciBzeXN0ZW0gVyA9IGludihYXlQgKiBYKSAqIFheVCAqIHkKdm9pZCBtYXRyaXhfdmVjdG9yX211bHRpcGx5KGRvdWJsZSBtYXRyaXhbQ09MU11bQ09MU10sIGRvdWJsZSB2ZWN0b3JbQ09MU10sIGRvdWJsZSByZXN1bHRbQ09MU10pIHsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQ09MUzsgKytpKSB7CiAgICAgICAgcmVzdWx0W2ldID0gMDsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IENPTFM7ICsraikgewogICAgICAgICAgICByZXN1bHRbaV0gKz0gbWF0cml4W2ldW2pdICogdmVjdG9yW2pdOwogICAgICAgIH0KICAgIH0KfQoKaW50IG1haW4oKSB7CiAgICAvLyBQcm92aWRlZCBkYXRhc2V0CiAgICBkb3VibGUgZGF0YVtST1dTXVszXSA9IHsKICAgICAgICB7My44NSwgMy44LCA3LjM4fSwgezMuNzUsIDQsIDguNTF9LCB7My43LCA0LjMsIDkuNTJ9LCB7My43LCAzLjcsIDcuNX0sIHszLjYsIDMuODUsIDkuMzN9LAogICAgICAgIHszLjYsIDMuOCwgOC4yOH0sIHszLjYsIDMuNzUsIDguNzV9LCB7My44LCAzLjg1LCA3Ljg3fSwgezMuOCwgMy42NSwgNy4xfSwgezMuODUsIDQsIDh9LAogICAgICAgIHszLjksIDQuMSwgNy44OX0sIHszLjksIDQsIDguMTV9LCB7My43LCA0LjEsIDkuMX0sIHszLjc1LCA0LjIsIDguODZ9LCB7My43NSwgNC4xLCA4Ljl9LAogICAgICAgIHszLjgsIDQuMSwgOC44N30sIHszLjcsIDQuMywgOX0sIHszLjcsIDQuMSwgOC43NX0sIHszLjgsIDMuNzUsIDcuOTV9LCB7My44LCAzLjc1LCA3LjY1fSwKICAgICAgICB7My43NSwgMy42NSwgNy4yN30sIHszLjcsIDMuOSwgOH0sIHszLjU1LCAzLjY1LCA4LjV9LCB7My42LCA0LjEsIDguNzV9LCB7My42NSwgNC4yNSwgOS4yMX0sCiAgICAgICAgezMuNywgMy42NSwgOC4yN30sIHszLjc1LCAzLjc1LCA3LjY3fSwgezMuOCwgMy44NSwgNy45M30sIHszLjcsIDQuMjUsIDkuMjZ9CiAgICB9OwoKICAgIC8vIEluaXRpYWxpemUgbWF0cmljZXMKICAgIGRvdWJsZSBYW1JPV1NdW0NPTFNdOwogICAgZG91YmxlIFh0W0NPTFNdW1JPV1NdOwogICAgZG91YmxlIFh0WFtDT0xTXVtDT0xTXTsKICAgIGRvdWJsZSBYdFhfaW52W0NPTFNdW0NPTFNdOwogICAgZG91YmxlIHlbUk9XU107CiAgICBkb3VibGUgWHR5W0NPTFNdOwogICAgZG91YmxlIFdbQ09MU107CgogICAgLy8gUG9wdWxhdGUgbWF0cmljZXMgWCBhbmQgdmVjdG9yIHkKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUk9XUzsgKytpKSB7CiAgICAgICAgWFtpXVswXSA9IDEuMDsgLy8gRmlyc3QgY29sdW1uIG9mIG9uZXMKICAgICAgICBYW2ldWzFdID0gZGF0YVtpXVswXTsgLy8geDEgY29sdW1uCiAgICAgICAgWFtpXVsyXSA9IGRhdGFbaV1bMV07IC8vIHgyIGNvbHVtbgogICAgICAgIFhbaV1bM10gPSBkYXRhW2ldWzBdICogZGF0YVtpXVswXTsgLy8geDFeMiBjb2x1bW4KICAgICAgICBYW2ldWzRdID0gZGF0YVtpXVsxXSAqIGRhdGFbaV1bMV07IC8vIHgyXjIgY29sdW1uCiAgICAgICAgeVtpXSA9IGRhdGFbaV1bMl07CiAgICB9CgogICAgLy8gVHJhbnNwb3NlIG9mIFgKICAgIG1hdHJpeF90cmFuc3Bvc2UoWCwgWHQpOwoKICAgIC8vIFh0ICogWAogICAgbWF0cml4X211bHRpcGx5KFh0LCBYLCBYdFgpOwoKICAgIC8vIEludmVyc2Ugb2YgWHQgKiBYCiAgICBtYXRyaXhfaW52ZXJzZShYdFgsIFh0WF9pbnYpOwoKICAgIC8vIFh0ICogeQogICAgbWF0cml4X3ZlY3Rvcl9tdWx0aXBseShYdCwgeSwgWHR5KTsKCiAgICAvLyBXID0gaW52KFh0WCkgKiBYdHkKICAgIG1hdHJpeF92ZWN0b3JfbXVsdGlwbHkoWHRYX2ludiwgWHR5LCBXKTsKCiAgICAvLyBQcmludCB0aGUgcmVzdWx0CiAgICBwcmludGYoIkNhbGN1bGF0ZWQgV15UOlxuIik7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IENPTFM7ICsraSkgewogICAgICAgIHByaW50ZigiJWxmICIsIFdbaV0pOwogICAgfQogICAgcHJpbnRmKCJcbiIpOwoKICAgIHJldHVybiAwOwp9Cg==