Object-oriented Scientific Computing Library: Version 0.910
Defines
vec_arith.h File Reference

Vector and matrix arithmetic. More...

#include <iostream>
#include <complex>
#include <o2scl/ovector_tlate.h>
#include <o2scl/omatrix_tlate.h>
#include <o2scl/uvector_tlate.h>
#include <o2scl/umatrix_tlate.h>
#include <o2scl/ovector_cx_tlate.h>
#include <o2scl/omatrix_cx_tlate.h>
#include <o2scl/uvector_cx_tlate.h>
#include <o2scl/umatrix_cx_tlate.h>

Go to the source code of this file.


Detailed Description

By default, the following operators are defined:

    ovector operator+(ovector_const_view &x, ovector_const_view &y);
    ovector operator+(ovector_const_view &x, uvector_const_view &y);
    ovector operator+(uvector_const_view &x, ovector_const_view &y);
    uvector operator+(uvector_const_view &x, uvector_const_view &y);

    ovector_cx operator+(ovector_cx_view &x, ovector_cx_view &y);
    ovector_cx operator+(ovector_cx_view &x, uvector_cx_view &y);
    ovector_cx operator+(uvector_cx_view &x, ovector_cx_view &y);
    uvector_cx operator+(uvector_cx_view &x, uvector_cx_view &y);
    
    ovector operator-(ovector_const_view &x, ovector_const_view &y);
    ovector operator-(ovector_const_view &x, uvector_const_view &y);
    ovector operator-(uvector_const_view &x, ovector_const_view &y);
    uvector operator-(uvector_const_view &x, uvector_const_view &y);

    ovector_cx operator-(ovector_cx_view &x, ovector_cx_view &y);
    ovector_cx operator-(ovector_cx_view &x, uvector_cx_view &y);
    ovector_cx operator-(uvector_cx_view &x, ovector_cx_view &y);
    uvector_cx operator-(uvector_cx_view &x, uvector_cx_view &y);
    
    ovector operator*(omatrix_const_view &x, ovector_const_view &y);
    ovector operator*(omatrix_const_view &x, uvector_const_view &y);
    ovector operator*(umatrix_const_view &x, ovector_const_view &y);
    uvector operator*(umatrix_const_view &x, uvector_const_view &y);

    ovector_cx operator*(omatrix_cx_view &x, ovector_cx_view &y);
    ovector_cx operator*(omatrix_cx_view &x, uvector_cx_view &y);
    ovector_cx operator*(umatrix_cx_view &x, ovector_cx_view &y);
    uvector_cx operator*(umatrix_cx_view &x, uvector_cx_view &y);

    ovector operator*(ovector_const_view &x, omatrix_const_view &y);
    ovector operator*(ovector_const_view &x, umatrix_const_view &y);
    ovector operator*(uvector_const_view &x, omatrix_const_view &y);
    uvector operator*(ovector_const_view &x, umatrix_const_view &y);

    ovector trans_mult(ovector_const_view &x, omatrix_const_view &y);
    ovector trans_mult(ovector_const_view &x, umatrix_const_view &y);
    ovector trans_mult(uvector_const_view &x, omatrix_const_view &y);
    uvector trans_mult(ovector_const_view &x, umatrix_const_view &y);

    double dot(ovector_const_view &x, ovector_const_view &y);
    double dot(ovector_const_view &x, uvector_const_view &y);
    double dot(uvector_const_view &x, ovector_const_view &y);
    double dot(uvector_const_view &x, uvector_const_view &y);

    double dot(ovector_cx_view &x, ovector_cx_view &y);
    double dot(ovector_cx_view &x, uvector_cx_view &y);
    double dot(uvector_cx_view &x, ovector_cx_view &y);
    double dot(uvector_cx_view &x, uvector_cx_view &y);

    ovector operator*(double x, ovector_const_view &y);
    uvector operator*(double x, uvector_const_view &y);
    ovector operator*(ovector_const_view &x, double y);
    uvector operator*(uvector_const_view &x, double y);
    
    ovector pair_prod(ovector_const_view &x, ovector_const_view &y);
    ovector pair_prod(ovector_const_view &x, uvector_const_view &y);
    ovector pair_prod(uvector_const_view &x, ovector_const_view &y);
    uvector pair_prod(uvector_const_view &x, uvector_const_view &y);

    ovector_cx pair_prod(ovector_cx_view &x, ovector_const_view &y);
    ovector_cx pair_prod(ovector_cx_view &x, uvector_const_view &y);
    ovector_cx pair_prod(uvector_cx_view &x, ovector_const_view &y);
    uvector_cx pair_prod(uvector_cx_view &x, uvector_const_view &y);
    ovector_cx pair_prod(ovector_const_view &x, ovector_cx_view &y);
    ovector_cx pair_prod(ovector_const_view &x, uvector_cx_view &y);
    ovector_cx pair_prod(uvector_const_view &x, ovector_cx_view &y);
    uvector_cx pair_prod(uvector_const_view &x, uvector_cx_view &y);
    ovector_cx pair_prod(ovector_cx_view &x, ovector_cx_view &y);
    ovector_cx pair_prod(ovector_cx_view &x, uvector_cx_view &y);
    ovector_cx pair_prod(uvector_cx_view &x, ovector_cx_view &y);
    uvector_cx pair_prod(uvector_cx_view &x, uvector_cx_view &y);

    bool operator==(ovector_const_view &x, ovector_const_view &y);
    bool operator==(ovector_const_view &x, uvector_const_view &y);
    bool operator==(uvector_const_view &x, ovector_const_view &y);
    bool operator==(uvector_const_view &x, uvector_const_view &y);

    bool operator!=(ovector_const_view &x, ovector_const_view &y);
    bool operator!=(ovector_const_view &x, uvector_const_view &y);
    bool operator!=(uvector_const_view &x, ovector_const_view &y);
    bool operator!=(uvector_const_view &x, uvector_const_view &y);
Note:
This used to be in a separate namespace, called o2scl_arith, but this causes problems with Koenig lookup in template classes for operator*() when defined for vector addition (for example).
Idea for Future:
Define operators for complex vector * real matrix
Idea for Future:
Define == and != for complex vectors
Idea for Future:
These should be replaced by the BLAS routines where possible?

Definition in file vec_arith.h.

Defines

#define O2SCL_OP_VEC_VEC_ADD(vec1, vec2, vec3)
 The header macro for vector-vector addition.
#define O2SCL_OP_VEC_VEC_SUB(vec1, vec2, vec3)
 The header macro for vector-vector subtraction.
#define O2SCL_OP_MAT_VEC_MULT(vec1, vec2, mat)
 The header macro for matrix-vector (right) multiplication.
#define O2SCL_OP_CMAT_CVEC_MULT(vec1, vec2, mat)
 The header macro for complex matrix-vector (right) multiplication.
#define O2SCL_OP_VEC_MAT_MULT(vec1, vec2, mat)
 The header macro for vector-matrix (left) multiplication.
#define O2SCL_OP_TRANS_MULT(vec1, vec2, mat)
 The header macro for the trans_mult form of vector * matrix.
#define O2SCL_OP_DOT_PROD(dtype, vec1, vec2)
 The header macro for vector scalar (dot) product.
#define O2SCL_OP_CX_DOT_PROD(dtype, vec1, vec2)
 The header macro for complex vector scalar (dot) product.
#define O2SCL_OP_SCA_VEC_MULT(dtype, vecv, vec)
 The header macro for scalar-vector multiplication.
#define O2SCL_OP_VEC_SCA_MULT(dtype, vecv, vec)
 The header macro for vector-scalar multiplication.
#define O2SCL_OP_VEC_VEC_PRO(vec1, vec2, vec3)
 The header macro for pairwise vector * vector (where either vector can be real or complex)
#define O2SCL_OPSRC_VEC_VEC_ADD(vec1, vec2, vec3)
 The source code macro for vector-vector addition.
#define O2SCL_OPSRC_VEC_VEC_SUB(vec1, vec2, vec3)
 The source code macro for vector-vector subtraction.
#define O2SCL_OPSRC_MAT_VEC_MULT(vec1, vec2, mat)
 The source code macro for matrix * vector.
#define O2SCL_OPSRC_CMAT_CVEC_MULT(vec1, vec2, mat)
 The source code macro for complex matrix * complex vector.
#define O2SCL_OPSRC_VEC_MAT_MULT(vec1, vec2, mat)
 The source code macro for the operator form of vector * matrix.
#define O2SCL_OPSRC_TRANS_MULT(vec1, vec2, mat)
 The source code macro for the trans_mult form of vector * matrix.
#define O2SCL_OPSRC_DOT_PROD(dtype, vec1, vec2)
 The source code macro for a vector dot product.
#define O2SCL_OPSRC_CX_DOT_PROD(dtype, vec1, vec2)
 The source code macro for a complex vector dot product.
#define O2SCL_OPSRC_SCA_VEC_MULT(dtype, vecv, vec)
 The source code macro for vector=scalar*vector.
#define O2SCL_OPSRC_VEC_SCA_MULT(dtype, vecv, vec)
 The source code macro for vector=vector*scalar.
#define O2SCL_OPSRC_VEC_VEC_PRO(vec1, vec2, vec3)
 The source code macro for pairwise vector * vector (where either vector can be real or complex)
#define O2SCL_OP_VEC_VEC_EQUAL(vec1, vec2)
 The header macro for vector==vector.
#define O2SCL_OPSRC_VEC_VEC_EQUAL(vec1, vec2)
 The source code macro vector==vector.
#define O2SCL_OP_VEC_VEC_NEQUAL(vec1, vec2)
 The header macro for vector!=vector.
#define O2SCL_OPSRC_VEC_VEC_NEQUAL(vec1, vec2)
 The source code macro vector!=vector.

Define Documentation

#define O2SCL_OP_VEC_VEC_ADD (   vec1,
  vec2,
  vec3 
)
Value:
vec1 operator+  \
    (const vec2 &x, const vec3 &y);

Given types vec1, vec2, and vec_3, this macro provides the function declaration for adding two vectors using the form

      vec1 operator+(const vec2 &x, const vec3 &y);

The corresponding definition is given in O2SCL_OPSRC_VEC_VEC_ADD.

Note:
This used to be in a separate namespace, called o2scl_arith, but this causes problems with Koenig lookup in template classes for operator*() when defined for vector addition (for example).

Definition at line 158 of file vec_arith.h.

#define O2SCL_OP_VEC_VEC_SUB (   vec1,
  vec2,
  vec3 
)
Value:
vec1 operator-  \
    (const vec2 &x, const vec3 &y);

Given types vec1, vec2, and vec_3, this macro provides the function declaration for adding two vectors using the form

      vec1 operator-(const vec2 &x, const vec3 &y);

The corresponding definition is given in O2SCL_OPSRC_VEC_VEC_SUB.

Definition at line 199 of file vec_arith.h.

#define O2SCL_OP_MAT_VEC_MULT (   vec1,
  vec2,
  mat 
)
Value:
vec1 operator*  \
    (const mat &m, const vec2 &x);

Given types vec1, vec2, and mat, this macro provides the function declaration for adding two vectors using the form

      vec1 operator*(const mat &m, const vec3 &x);

See also the blas version of this function dgemv().

The corresponding definition is given in O2SCL_OPSRC_MAT_VEC_MULT.

Definition at line 243 of file vec_arith.h.

#define O2SCL_OP_CMAT_CVEC_MULT (   vec1,
  vec2,
  mat 
)
Value:
vec1 operator*  \
    (const mat &m, const vec2 &x);

Given types vec1, vec2, and mat, this macro provides the function declaration for adding two vectors using the form

      vec1 operator*(const mat &m, const vec3 &x);

The corresponding definition is given in O2SCL_OPSRC_CMAT_CVEC_MULT.

Definition at line 278 of file vec_arith.h.

#define O2SCL_OP_VEC_MAT_MULT (   vec1,
  vec2,
  mat 
)
Value:
vec1 operator*  \
    (const vec2 &x, const mat &m);

Given types vec1, vec2, and mat, this macro provides the function declaration for adding two vectors using the form

      vec1 operator*(const vec3 &x, const mat &m);

The corresponding definition is given in O2SCL_OPSRC_VEC_MAT_MULT.

Definition at line 312 of file vec_arith.h.

#define O2SCL_OP_TRANS_MULT (   vec1,
  vec2,
  mat 
)
Value:
vec1 trans_mult \
    (const vec2 &x, const mat &m);

Definition at line 334 of file vec_arith.h.

#define O2SCL_OP_DOT_PROD (   dtype,
  vec1,
  vec2 
)
Value:
dtype dot       \
    (const vec1 &x, const vec2 &y);

Given types vec1, vec2, and dtype, this macro provides the function declaration for adding two vectors using the form

      dtype operator*(const vec1 &x, const vec2 &y);

The corresponding definition is given in O2SCL_OPSRC_DOT_PROD.

Definition at line 367 of file vec_arith.h.

#define O2SCL_OP_CX_DOT_PROD (   dtype,
  vec1,
  vec2 
)
Value:
dtype dot       \
    (const vec1 &x, const vec2 &y);

Given types vec1, vec2, and dtype, this macro provides the function declaration for adding two vectors using the form

      dtype operator*(const vec1 &x, const vec2 &y);

The corresponding definition is given in O2SCL_OPSRC_CX_DOT_PROD.

Definition at line 401 of file vec_arith.h.

#define O2SCL_OP_SCA_VEC_MULT (   dtype,
  vecv,
  vec 
)
Value:
vec operator*   \
    (const dtype &x, const vecv &y);

Given types vecv, vec, and dtype, this macro provides the function declaration for adding two vectors using the form

      vec operator*(const dtype &x, const vecv &y);

The corresponding definition is given in O2SCL_OPSRC_SCA_VEC_MULT.

Definition at line 434 of file vec_arith.h.

#define O2SCL_OP_VEC_SCA_MULT (   dtype,
  vecv,
  vec 
)
Value:
vec operator*   \
    (const vecv &x, const dtype &y);

Given types vecv, vec, and dtype, this macro provides the function declaration for adding two vectors using the form

      vec operator*(const vecv &x, const dtype &y);

The corresponding definition is given in O2SCL_OPSRC_VEC_SCA_MULT.

Definition at line 461 of file vec_arith.h.

#define O2SCL_OP_VEC_VEC_PRO (   vec1,
  vec2,
  vec3 
)
Value:
vec1 pair_prod  \
    (const vec2 &x, const vec3 &y);

Given types vec1, vec2, and vec3, this macro provides the function declaration for adding two vectors using the form

      vec1 pair_prod(const vec2 &x, const vec3 &y);

The corresponding definition is given in O2SCL_OPSRC_VEC_VEC_PRO.

Definition at line 489 of file vec_arith.h.

#define O2SCL_OPSRC_VEC_VEC_ADD (   vec1,
  vec2,
  vec3 
)
Value:
vec1 o2scl::operator+ \
      (const vec2 &x, const vec3 &y) {                                  \
      size_t m=x.size();                                                \
      if (y.size()<m) m=y.size();                                       \
      vec1 r(m);                                                        \
      for(size_t i=0;i<m;i++) {                                         \
        r[i]=x[i]+y[i];                                                 \
      }                                                                 \
      return r;                                                         \
    }

This define macro generates the function definition. See the function declaration O2SCL_OP_VEC_VEC_ADD

Definition at line 534 of file vec_arith.h.

#define O2SCL_OPSRC_VEC_VEC_SUB (   vec1,
  vec2,
  vec3 
)
Value:
vec1 o2scl::operator- \
      (const vec2 &x, const vec3 &y) {                                  \
      size_t m=x.size();                                                \
      if (y.size()<m) m=y.size();                                       \
      vec1 r(m);                                                        \
      for(size_t i=0;i<m;i++) {                                         \
        r[i]=x[i]-y[i];                                                 \
      }                                                                 \
      return r;                                                         \
    }

This define macro generates the function definition. See the function declaration O2SCL_OP_VEC_VEC_SUB

Definition at line 550 of file vec_arith.h.

#define O2SCL_OPSRC_MAT_VEC_MULT (   vec1,
  vec2,
  mat 
)
Value:
vec1 o2scl::operator* \
      (const mat &m, const vec2 &x) {                                   \
      size_t nr=m.rows();                                               \
      size_t nc=m.cols();                                               \
      vec1 res(nr);                                                     \
      for(size_t i=0;i<nr;i++) {                                        \
        double r=0.0;                                                   \
        for(size_t j=0;j<nc;j++) {                                      \
          r+=m[i][j]*x[j];                                              \
        }                                                               \
        res[i]=r;                                                       \
      }                                                                 \
      return res;                                                       \
    }

This define macro generates the function definition. See the function declaration O2SCL_OP_MAT_VEC_MULT

Definition at line 566 of file vec_arith.h.

#define O2SCL_OPSRC_CMAT_CVEC_MULT (   vec1,
  vec2,
  mat 
)
Value:
vec1 o2scl::operator* \
      (const mat &m, const vec2 &x) {                                   \
      size_t nr=m.rows();                                               \
      size_t nc=m.cols();                                               \
      vec1 res(nr);                                                     \
      for(size_t i=0;i<nr;i++) {                                        \
        double re=0.0;                                                  \
        double im=0.0;                                                  \
        for(size_t j=0;j<nc;j++) {                                      \
          gsl_complex g=m[i][j]*x[j];                                   \
          re+=g.dat[0];                                                 \
          im+=g.dat[1];                                                 \
        }                                                               \
        res[i].dat[0]=re;                                               \
        res[i].dat[1]=im;                                               \
      }                                                                 \
      return res;                                                       \
    }

This define macro generates the function definition. See the function declaration O2SCL_OP_CMAT_CVEC_MULT

Definition at line 586 of file vec_arith.h.

#define O2SCL_OPSRC_VEC_MAT_MULT (   vec1,
  vec2,
  mat 
)
Value:
vec1 o2scl::operator* \
      (const vec2 &x, const mat &m) {                                   \
      size_t nr=m.rows();                                               \
      size_t nc=m.cols();                                               \
      vec1 res(nr);                                                     \
      for(size_t j=0;j<nc;j++) {                                        \
        double r=0.0;                                                   \
        for(size_t i=0;i<nr;i++) {                                      \
          r+=x[i]*m[i][j];                                              \
        }                                                               \
        res[j]=r;                                                       \
      }                                                                 \
      return res;                                                       \
    }

This define macro generates the function definition. See the function declaration O2SCL_OP_VEC_MAT_MULT

Definition at line 610 of file vec_arith.h.

#define O2SCL_OPSRC_TRANS_MULT (   vec1,
  vec2,
  mat 
)
Value:
vec1 o2scl::trans_mult \
      (const vec2 &x, const mat &m) {                                   \
      size_t nr=m.rows();                                               \
      size_t nc=m.cols();                                               \
      vec1 res(nr);                                                     \
      for(size_t j=0;j<nc;j++) {                                        \
        double r=0.0;                                                   \
        for(size_t i=0;i<nr;i++) {                                      \
          r+=x[i]*m[i][j];                                              \
        }                                                               \
        res[j]=r;                                                       \
      }                                                                 \
      return res;                                                       \
    }

This define macro generates the function definition. See the function declaration O2SCL_OP_TRANS_MULT

Definition at line 631 of file vec_arith.h.

#define O2SCL_OPSRC_DOT_PROD (   dtype,
  vec1,
  vec2 
)
Value:
dtype o2scl::dot        \
      (const vec1 &x, const vec2 &y) {                                  \
      size_t m=x.size();                                                \
      if (y.size()<m) m=y.size();                                       \
      dtype r=0;                                                        \
      for(size_t i=0;i<m;i++) {                                         \
        r+=x[i]*y[i];                                                   \
      }                                                                 \
      return r;                                                         \
    }

This define macro generates the function definition. See the function declaration O2SCL_OP_DOT_PROD

Definition at line 651 of file vec_arith.h.

#define O2SCL_OPSRC_CX_DOT_PROD (   dtype,
  vec1,
  vec2 
)
Value:
dtype o2scl::dot        \
      (const vec1 &x, const vec2 &y) {                                  \
      size_t m=x.size();                                                \
      if (y.size()<m) m=y.size();                                       \
      dtype r={{0.0,0.0}};                                              \
      for(size_t i=0;i<m;i++) {                                         \
        r+=x[i]*y[i];                                                   \
      }                                                                 \
      return r;                                                         \
    }

This define macro generates the function definition. See the function declaration O2SCL_OP_CX_DOT_PROD

Definition at line 667 of file vec_arith.h.

#define O2SCL_OPSRC_SCA_VEC_MULT (   dtype,
  vecv,
  vec 
)
Value:
vec o2scl::operator* \
      (const dtype &x, const vecv &y) {                                 \
      size_t m=y.size();                                                \
      vec r(m);                                                         \
      for(size_t i=0;i<m;i++) {                                         \
        r[i]=x*y[i];                                                    \
      }                                                                 \
      return r;                                                         \
    }

This define macro generates the function definition. See the function declaration O2SCL_OP_SCA_VEC_MULT

Definition at line 683 of file vec_arith.h.

#define O2SCL_OPSRC_VEC_SCA_MULT (   dtype,
  vecv,
  vec 
)
Value:
vec o2scl::operator* \
      (const vecv &x, const dtype &y) {                                 \
      size_t m=x.size();                                                \
      vec r(m);                                                         \
      for(size_t i=0;i<m;i++) {                                         \
        r[i]=x[i]*y;                                                    \
      }                                                                 \
      return r;                                                         \
    }

This define macro generates the function definition. See the function declaration O2SCL_OP_VEC_SCA_MULT

Definition at line 698 of file vec_arith.h.

#define O2SCL_OPSRC_VEC_VEC_PRO (   vec1,
  vec2,
  vec3 
)
Value:
vec1 o2scl::pair_prod \
      (const vec2 &x, const vec3 &y) {                                  \
      size_t m=x.size();                                                \
      if (y.size()<m) m=y.size();                                       \
      vec1 r(m);                                                        \
      for(size_t i=0;i<m;i++) {                                         \
        r[i]=x[i]*y[i];                                                 \
      }                                                                 \
      return r;                                                         \
    }

This define macro generates the function definition. See the function declaration O2SCL_OP_VEC_VEC_PRO

Definition at line 714 of file vec_arith.h.

#define O2SCL_OP_VEC_VEC_EQUAL (   vec1,
  vec2 
)
Value:
bool operator== \
      (const vec1 &x, const vec2 &y);

Given types vec1 and vec2, this macro provides the function declaration for vector equality comparisons using

        bool operator==(const vec1 &x, const vec2 &y);
Note:
Two vectors with different sizes are defined to be not equal, no matter what their contents.

The corresponding definition is given in O2SCL_OPSRC_VEC_VEC_EQUAL.

Definition at line 739 of file vec_arith.h.

#define O2SCL_OPSRC_VEC_VEC_EQUAL (   vec1,
  vec2 
)
Value:
bool o2scl::operator== \
    (const vec1 &x, const vec2 &y) {                                    \
    size_t m=x.size();                                                  \
    size_t n=y.size();                                                  \
    if (m!=n) return false;                                             \
    for(size_t i=0;i<m;i++) {                                           \
      if (x[i]!=y[i]) return false;                                     \
    }                                                                   \
    return true;                                                        \
  }
Note:
Two vectors with different sizes are defined to be not equal, no matter what their contents.

This define macro generates the function definition. See the function declaration O2SCL_OP_VEC_VEC_EQUAL

Definition at line 794 of file vec_arith.h.

#define O2SCL_OP_VEC_VEC_NEQUAL (   vec1,
  vec2 
)
Value:
bool operator!= \
    (const vec1 &x, const vec2 &y);

Given types vec1 and vec2, this macro provides the function declaration for vector inequality comparisons using

      bool operator==(const vec1 &x, const vec2 &y);
Note:
Two vectors with different sizes are defined to be not equal, no matter what their contents.

The corresponding definition is given in O2SCL_OPSRC_VEC_VEC_NEQUAL.

Definition at line 819 of file vec_arith.h.

#define O2SCL_OPSRC_VEC_VEC_NEQUAL (   vec1,
  vec2 
)
Value:
bool o2scl::operator!= \
    (const vec1 &x, const vec2 &y) {                                    \
    size_t m=x.size();                                                  \
    size_t n=y.size();                                                  \
    if (m!=n) return true;                                              \
    for(size_t i=0;i<m;i++) {                                           \
      if (x[i]!=y[i]) return true;                                      \
    }                                                                   \
    return false;                                                       \
  }
Note:
Two vectors with different sizes are defined to be not equal, no matter what their contents.

This define macro generates the function definition. See the function declaration O2SCL_OP_VEC_VEC_NEQUAL

Definition at line 874 of file vec_arith.h.

 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.