I don't understand what the error is in calculating the system of linear equations.
I need to solve a system of linear equations using the Scilab API in C, but I'm getting values that are too small. Checked the solution, the answer should be: [0;1]
.
Free is specially commented because the program crashes immediately.
I thought the error was in dgesv_
, but it's strange since it's a Scilab function and why it's solved incorrectly. Maybe something is wrong with the output?
Code:
#include "api_scilab.h"
#include "Scierror.h"
#include "BOOL.h"
#include "localization.h"
extern void dgesv_(int* n, int* nrhs, double* A, int* lda, int* ipiv, double* b, int* ldb, int* info);
static const char fname[] = "foo6";
int sci_foo6(scilabEnv env, int nin, scilabVar* in, int nopt, scilabOpt* opt, int nout, scilabVar* out)
{
int i = 0;
int n = 0; // System dimension
double* A = NULL; // Coefficient matrix
double* b = NULL; // Right-hand side vector
double* x = NULL; // Solution
int info = 0;
/* Check the number of input and output arguments */
if (nin != 2 || nout != 1) {
Scierror(77, _("%s: Wrong number of input or output arguments: 2 inputs and 1 output expected.\n"), fname);
return 1;
}
/* Check the types of input arguments */
if (scilab_isDouble(env, in[0]) == 0 || scilab_isMatrix2d(env, in[0]) == 0 ||
scilab_isComplex(env, in[0]) == 1 || scilab_isDouble(env, in[1]) == 0 ||
scilab_isMatrix2d(env, in[1]) == 0 || scilab_isComplex(env, in[1]) == 1) {
Scierror(999, _("%s: Wrong type for input arguments. Double matrices expected.\n"), fname);
return 1;
}
/* Get the dimension of the coefficient matrix */
int rowA = 0, colA = 0, rowB = 0, colB = 0;
scilab_getDim2d(env, in[0], &rowA, &colA);
scilab_getDim2d(env, in[1], &rowB, &colB);
if (rowA != colA || rowB != rowA || colB != 1) {
Scierror(999, _("%s: Incorrect dimensions. Coefficient matrix should be square and vector should be a column vector of the same size.\n"), fname);
return 1;
}
n = rowA;
/* Get data from input arguments */
scilab_getDoubleArray(env, in[0], &A);
scilab_getDoubleArray(env, in[1], &b);
/* Solve the system of linear equations */
x = (double*)malloc(n * sizeof(double));
dgesv_(&n, &n, A, &n, b, x, &n, &info);
if (info != 0) {
Scierror(999, _("%s: LAPACK dgesv function failed with error code %d.\n"), fname, info);
free(x);
return 1;
}
/* Create the output argument and copy the result */
out[0] = scilab_createDoubleMatrix2d(env, 1, n, 0);
double* xPtr = NULL;
scilab_getDoubleArray(env, out[0], &xPtr);
for (i = 0; i < n; i++) {
xPtr[i] = x[i];
}
//free(x);
return 0;
}
Conclusion:
--> A = [2, 1; -1, 2];
--> b = [1; 2];
--> x = foo6(A, b);
--> disp(x);
5.27D-314 2.64D-314
Tried solving the SLAU through the Scilab API, but didn't get much out of it. I'm not sure if I'm doing it right.
See the below fixed code, yours above had several issues:
#include "api_scilab.h"
#include "Scierror.h"
#include "BOOL.h"
#include "localization.h"
extern void dgesv_(int* n, int* nrhs, double* A, int* lda, int* ipiv, double* b, int* ldb, int* info);
static const char fname[] = "foo6";
int sci_foo6(scilabEnv env, int nin, scilabVar* in, int nopt, scilabOpt* opt, int nout, scilabVar* out)
{
int i = 0;
int n = 0; // System dimension
int iOne = 1;
double* A = NULL; // Coefficient matrix
double* b = NULL; // Right-hand side vector
double* x = NULL; // Solution
int* iPiv = NULL;
int info = 0;
/* Check the number of input and output arguments */
if (nin != 2 || nout != 1) {
Scierror(77, _("%s: Wrong number of input or output arguments: 2 inputs and 1 output expected.\n"), fname);
return 1;
}
/* Check the types of input arguments */
if (scilab_isDouble(env, in[0]) == 0 || scilab_isMatrix2d(env, in[0]) == 0 ||
scilab_isComplex(env, in[0]) == 1 || scilab_isDouble(env, in[1]) == 0 ||
scilab_isMatrix2d(env, in[1]) == 0 || scilab_isComplex(env, in[1]) == 1) {
Scierror(999, _("%s: Wrong type for input arguments. Double matrices expected.\n"), fname);
return 1;
}
/* Get the dimension of the coefficient matrix */
int rowA = 0, colA = 0, rowB = 0, colB = 0;
scilab_getDim2d(env, in[0], &rowA, &colA);
scilab_getDim2d(env, in[1], &rowB, &colB);
if (rowA != colA || rowB != rowA || colB != 1) {
Scierror(999, _("%s: Incorrect dimensions. Coefficient matrix should be square and vector should be a column vector of the same size.\n"), fname);
return 1;
}
n = rowA;
/* Get data from input arguments */
scilab_getDoubleArray(env, in[0], &A);
scilab_getDoubleArray(env, in[1], &b);
/* Solve the system of linear equations */
x = (double*)malloc(n * sizeof(double));
for (i = 0; i < n; i++) {
x[i] = b[i];
}
iPiv = (int*)malloc(n * sizeof(int));
dgesv_(&n, &iOne, A, &n, iPiv, x, &n, &info);
if (info != 0) {
Scierror(999, _("%s: LAPACK dgesv function failed with error code %d.\n"), fname, info);
free(x);
free(iPiv);
return 1;
}
/* Create the output argument and copy the result */
out[0] = scilab_createDoubleMatrix2d(env, 1, n, 0);
double* xPtr = NULL;
scilab_getDoubleArray(env, out[0], &xPtr);
for (i = 0; i < n; i++) {
xPtr[i] = x[i];
}
free(x);
free(iPiv);
return 0;
}
Instructions to compile and link were not given (the source above is supposed to be saved in sci_foo6.c
):
ilib_build('foo6',['foo6','sci_foo6','csci6'],"sci_foo6.c",[]);
exec loader.sce
Then the solution is correctly computed:
--> A = [2, 1; -1, 2];
--> b = [1;2];
--> x = foo6(A,b)
x =
0. 1.