How to implement a left matrix division on C++ using gsl - c++

I am trying to port a MATLAB program to C++.
And I want to implement a left matrix division between a matrix A and a column vector B.
A is an m-by-n matrix with m is not equal to n and B is a column vector with m components.
And I want the result X = A\B is the solution in the least squares sense to the under- or overdetermined system of equations AX = B. In other words, X minimizes norm(A*X - B), the length of the vector AX - B.
That means I want it has the same result as the A\B in MATLAB.
I want to implement this feature in GSL-GNU (GNU Science Library) and I don't know too much about math, least square fitting or matrix operation, can somebody told me how to do this in GSL? Or if implement them in GSL is too complicate, can someone suggest me a good open source C/C++ library that provides the above matrix operation?
Okay, I finally figure out by my self after spend another 5 hours on it.. But still thanks for the suggestions to my question.
Assuming we have a 5 * 2 matrix
A = [1 0
1 0
0 1
1 1
1 1]
and a vector b = [1.8388,2.5595,0.0462,2.1410,0.6750]
The solution to the A \ b would be
#include <stdio.h>
#include <gsl/gsl_linalg.h>
int
main (void)
{
double a_data[] = {1.0, 0.0,1.0, 0.0, 0.0,1.0,1.0,1.0,1.0,1.0};
double b_data[] = {1.8388,2.5595,0.0462,2.1410,0.6750};
gsl_matrix_view m
= gsl_matrix_view_array (a_data, 5, 2);
gsl_vector_view b
= gsl_vector_view_array (b_data, 5);
gsl_vector *x = gsl_vector_alloc (2); // size equal to n
gsl_vector *residual = gsl_vector_alloc (5); // size equal to m
gsl_vector *tau = gsl_vector_alloc (2); //size equal to min(m,n)
gsl_linalg_QR_decomp (&m.matrix, tau); //
gsl_linalg_QR_lssolve(&m.matrix, tau, &b.vector, x, residual);
printf ("x = \n");
gsl_vector_fprintf (stdout, x, "%g");
gsl_vector_free (x);
gsl_vector_free (tau);
gsl_vector_free (residual);
return 0;
}

In addition to the one you gave, a quick search revealed other GSL examples, one using QR decomposition, the other LU decomposition.
There exist other numeric libraries capable of solving linear systems (a basic functionality in every linear algebra library). For one, Armadillo offers a nice and readable interface:
#include <iostream>
#include <armadillo>
using namespace std;
using namespace arma;
int main()
{
mat A = randu<mat>(5,2);
vec b = randu<vec>(5);
vec x = solve(A, b);
cout << x << endl;
return 0;
}
Another good one is the Eigen library:
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
int main()
{
Matrix3f A;
Vector3f b;
A << 1,2,3, 4,5,6, 7,8,10;
b << 3, 3, 4;
Vector3f x = A.colPivHouseholderQr().solve(b);
cout << "The solution is:\n" << x << endl;
return 0;
}
Now, one thing to remember is that MLDIVIDE is a super-charged function and has multiple execution paths. If the coefficient matrix A has some special structure, then it is exploited to obtain faster or more accurate result (can choose from substitution algorithm, LU and QR factorization, ..)
MATLAB also has PINV which returns the minimal norm least-squares solution, in addition to a number of other iterative methods for solving systems of linear equations.

I'm not sure I understand your question, but if you've already found your solution using MATLAB, you may want to consider using MATLAB Coder, which automatically translates your MATLAB code into C++.

Related

How do I input a quadratic equation in C++?

We were given an assignment to program the following, which I have been trying to figure out how to solve for the last 2 hours but to no avail.
How do you actually solve a complex formula having different operations in one mathematical expression?
For you to properly understand which of the operations are to be solved in order, try recreating the quadratic equation, ax^2 + bx + c, in C++ on your own!
Instructions:
The value of a, b, c, and x are already provided for you in the code editor. Remake the formula using C++'s math functions and operators and store it into one variable.
Print the value of the variable that stores the formula. To understand which to actually solve first in the equation, try tracing it out by yourself and manually solve it and see if your answer match that of the sample output.
Sample output: 16
TL;DR I am told to recreate the quadratic equation on my own using the given variables with their values.
Here is my current output which failed:
#include<iostream>
#include <cmath>
int main(void) {
int a = 2;
int b = 2;
int c = 4;
int x = 2;
// TODO:
// 1. Compute for the result of the quadratic equation
// using the variables provided above and the math library
double result;
result = (a * x + b * x) pow(2, 2) + c;
// 2. Print the output required by the output sample
std::cout << result;
return 0;
}
It prints out 4 when it should be 16.
You use this code:
result = a * pow(x, 2) + b * x + c;

Fastest way to find complex roots

Using a + i b = sqrt(a*a + b*b) * exp(i arctan2(a,b)) I arrive at the following way to compute complex roots. However, I heard that trigonometric functions rather use up performance so I wonder if there is a better way in vanilla c++ (no external libaries).
Example: Let u+iv = sqrt(a+i b)
#include <math.h>
#include <iostream>
int main(){
double a = -1.;
double b = 0;
double r = sqrt(sqrt(a*a+b*b));
double phi = 0.5 * atan2(b, a);
double u = r * cos(phi);
double v = r * sin(phi);
std::cout << u << std::endl;
std::cout << v << "i" << std::endl;
}
This is just meant as a MWE, so it's not written in a class or method.
Yes there is! I'm going to link a good explanation of the process here, but it looks like this can be accomplished by only calculating the magnitude of the original number and subtracting out the real portion of the original number and finally taking the square root of that to find the imaginary part of the square root. The real part can be found by dividing the imaginary part of the original number by 2 * the imaginary part of the root to get your final answer.
https://www.qc.edu.hk/math/Advanced%20Level/Finding%20the%20square%20root%20of%20a%20complex%20number.htm
Let me know if you need more help with the code but this requires no trig functions.

Solving Systems of Linear Equations using Eigen

I'm currently working on a fluid simulation in C++, and part of the algorithm is to solve a sparse system of linear equations. People recommended using the library Eigen for this. I decided to test it out using this short program that I wrote:
#include <Eigen/SparseCholesky>
#include <vector>
#include <iostream>
int main() {
std::vector<Eigen::Triplet<double>> triplets;
triplets.push_back(Eigen::Triplet<double>(0, 0, 1));
triplets.push_back(Eigen::Triplet<double>(0, 1, -2));
triplets.push_back(Eigen::Triplet<double>(1, 0, 3));
triplets.push_back(Eigen::Triplet<double>(1, 1, -2));
Eigen::SparseMatrix<double> A(2, 2);
A.setFromTriplets(triplets.begin(), triplets.end());
Eigen::VectorXd b(2);
b[0] = -2;
b[1] = 2;
Eigen::SimplicialCholesky<Eigen::SparseMatrix<double>> chol(A);
Eigen::VectorXd x = chol.solve(b);
std::cout << x[0] << ' ' << x[1] << std::endl;
system("pause");
}
It gives it these two equations:
x - 2y = -2
3x - 2y = 2
The correct solution is:
x = 2
y = 2
But the problem is that when the program runs, it outputs:
0.181818 -0.727273
Which is totally wrong! I have been debugging this for hours, but it's a very short program and I'm following the tutorial on the Eigen website exactly. Does anybody know what is causing this issue?
P.S. I know that the classes I'm using are for sparse matrices, but the only difference between those and the normal Matrix classes is the way the elements are stored.
SimplicialCholesky is for symmetric positive definite (SPD) matrices, the matrix you assembled is not even symmetric. By default it only reads the entries in the lower triangular part ignoring the others, so it solved:
x + 3y = -2
3x -2y = 2
As you noticed, for non-symmetric square problems you need to use a direct solver based on LU or BICGSTAB in the world of iterative solvers. This is all summarized in the doc.
You should use a solver capable to process non-symmetric sparse matrices. Another possible approach is to seek a solution not of the original system [A]x=b, but [A]T*[A]x=[A]T*b, where [A]T stands for the [A] transpose. The latter system's matrix is symmetric and positive definite (as long as [A] is non-singular). The only shortcoming would be the fact that [A]T[A] may be rather ill-conditioned if the original [A] is not "good" in that sense. Just an example of software designed to solve such problems:
http://members.ozemail.com.au/~comecau/CMA_LS_Sparse.htm

Thin QR decomposition in c++

Is there an easy to use c++ library for "thin" QR decomposition of a rectangular matrix?
Eigen seems to only support full Q matrices. I can take a full Q and discard some columns, but would it be more efficient to not compute them to begin with?
Newmat does exactly what you want.
To decompose A into QR, you can do:
Matrix Q = A;
UpperTriangularMatrix R;
QRZ(Q, R)
If A is a 3x5 matrix, R will be 3x3 and Q will be 3x5 as well.
Even though this question is a bit old, for the record: Eigen does not explicitly compute the Q matrix, but a sequence of Householder vectors, which can directly be multiplied with any matrix (with the correct number of rows).
If you actually explicitly want the thin Q matrix, just multiply by an identity-matrix of the desired size:
#include <Eigen/QR>
#include <iostream>
int main()
{
using namespace Eigen;
MatrixXf A(MatrixXf::Random(5,3));
HouseholderQR<MatrixXf> qr(A);
MatrixXf thinQ = qr.householderQ() * MatrixXf::Identity(5,3);
std::cout << thinQ << '\n';
}

UMFPACK and BOOST's uBLAS Sparse Matrix

I am using Boost's uBLAS in a numerical code and have a 'heavy' solver in place:
http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?LU_Matrix_Inversion
The code works excellently, however, it is painfully slow. After some research, I found UMFPACK, which is a sparse matrix solver (among other things). My code generates large sparse matrices which I need to invert very frequently (more correctly solve, the value of the inverse matrix is irrelevant), so UMFPACk and BOOST's Sparse_Matrix class seems to be a happy marriage.
UMFPACK asks for the sparse matrix specified by three vectors: an entry count, row indexes, and the entries. (See example).
My question boils down to, can I get these three vectors efficiently from BOOST's Sparse Matrix class?
There is a binding for this:
http://mathema.tician.de/software/boost-numeric-bindings
The project seems to be two years stagnant, but it does the job well. An example use:
#include <iostream>
#include <boost/numeric/bindings/traits/ublas_vector.hpp>
#include <boost/numeric/bindings/traits/ublas_sparse.hpp>
#include <boost/numeric/bindings/umfpack/umfpack.hpp>
#include <boost/numeric/ublas/io.hpp>
namespace ublas = boost::numeric::ublas;
namespace umf = boost::numeric::bindings::umfpack;
int main() {
ublas::compressed_matrix<double, ublas::column_major, 0,
ublas::unbounded_array<int>, ublas::unbounded_array<double> > A (5,5,12);
ublas::vector<double> B (5), X (5);
A(0,0) = 2.; A(0,1) = 3;
A(1,0) = 3.; A(1,2) = 4.; A(1,4) = 6;
A(2,1) = -1.; A(2,2) = -3.; A(2,3) = 2.;
A(3,2) = 1.;
A(4,1) = 4.; A(4,2) = 2.; A(4,4) = 1.;
B(0) = 8.; B(1) = 45.; B(2) = -3.; B(3) = 3.; B(4) = 19.;
umf::symbolic_type<double> Symbolic;
umf::numeric_type<double> Numeric;
umf::symbolic (A, Symbolic);
umf::numeric (A, Symbolic, Numeric);
umf::solve (A, X, B, Numeric);
std::cout << X << std::endl; // output: [5](1,2,3,4,5)
}
NOTE:
Though this work, I am considering moving to NETLIB