<commit_before>/**************************************************************************************************
 *  cross.swift
 *
 *  This file defines singular value decomposition functionality. 
 *
 *  Author: <NAME>
 *  Creation Date: 29 Dec 2016
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the 
 *  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
 *  express or implied. See the License for the specific language governing permissions and 
 *  limitations under the License.
 *
 *  Copyright 2016 <NAME>
 **************************************************************************************************/

import CLapacke

/// Return the singular values of a given matrix.
///
/// - Parameters:
///    - A: matrix to find singular values of
/// - Returns: singular values of A, sorted in descending order
public func svd(_ A: Matrix<Double>) -> [Double]
{    

    let jobz: Int8 = 78 // ascii 'N'
    let m = Int32(A.rows)
    let n = Int32(A.columns)

    var a = A.data

    // The leading dimension equals the number of elements in the major dimension. In this case,
    // we are doing row-major so lda is the number of columns in A.
    let lda = n

    // s is a double array, dimension (min(M,N)). 
    // The singular values of A, sorted so that s(i) >= s(i+1).
    var s = [Double](repeating: 0.0, count: Int(min(m,n)))

    // U is not referenced since jobz='N'
    var u = [0.0]
    let ldu: Int32 = 1

    // VT is not referenced since jobz='N'
    var vt = [0.0]
    let ldvt = m    

    let info = LAPACKE_dgesdd(LAPACK_ROW_MAJOR, jobz, m, n, &a, lda, &s, &u, ldu, &vt, ldvt)
    precondition(info >= 0, "Illegal value in LAPACK argument \(-1*info)")
    if info > 0
    {
        print("Warning: DBDSDC did not converge, updating process failed.")
    }    

    return s
}

/// Perform a singular value decomposition of a given matrix.
///
/// - Parameters:
///    - A: matrix to find singular values of
/// - Returns: matrices U, S, and V such that A=U*S*transpose(V)
public func svd(_ A: Matrix<Double>) -> (U: Matrix<Double>, S: Matrix<Double>, V: Matrix<Double>)
{
    let jobz: Int8 = 65 // ascii 'A'
    let m = Int32(A.rows)
    let n = Int32(A.columns)<commit_msg>Function should return vector<commit_after>/**************************************************************************************************
 *  cross.swift
 *
 *  This file defines singular value decomposition functionality. 
 *
 *  Author: <NAME>
 *  Creation Date: 29 Dec 2016
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the 
 *  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
 *  express or implied. See the License for the specific language governing permissions and 
 *  limitations under the License.
 *
 *  Copyright 2016 <NAME>
 **************************************************************************************************/

import CLapacke


// TODO: figure out better way to request just the singular values; the way below is ambiguous 
// unless caller specifies the return type, which is just annoying.

/// Return the singular values of a given matrix.
///
/// - Parameters:
///    - A: matrix to find singular values of
/// - Returns: singular values of A, sorted in descending order
public func svd(_ A: Matrix<Double>) -> Vector<Double>
{    

    let jobz: Int8 = 78 // ascii 'N'
    let m = Int32(A.rows)
    let n = Int32(A.columns)

    var a = A.data

    // The leading dimension equals the number of elements in the major dimension. In this case,
    // we are doing row-major so lda is the number of columns in A.
    let lda = n

    // s is a double array, dimension (min(M,N)). 
    // The singular values of A, sorted so that s(i) >= s(i+1).
    var s = [Double](repeating: 0.0, count: Int(min(m,n)))

    // U is not referenced since jobz='N'
    var u = [0.0]
    let ldu: Int32 = 1

    // VT is not referenced since jobz='N'
    var vt = [0.0]
    let ldvt = m    

    let info = LAPACKE_dgesdd(LAPACK_ROW_MAJOR, jobz, m, n, &a, lda, &s, &u, ldu, &vt, ldvt)
    precondition(info >= 0, "Illegal value in LAPACK argument \(-1*info)")
    if info > 0
    {
        print("Warning: DBDSDC did not converge, updating process failed.")
    }    

    return Vector(s)
}

/// Perform a singular value decomposition of a given matrix.
///
/// - Parameters:
///    - A: matrix to find singular values of
/// - Returns: matrices U, S, and V such that A=U*S*transpose(V)
public func svd(_ A: Matrix<Double>) -> (U: Matrix<Double>, S: Matrix<Double>, V: Matrix<Double>)
{
    let jobz: Int8 = 65 // ascii 'A'
    let m = Int32(A.rows)
    let n = Int32(A.columns)
{'fraction_non_alphanumeric': 0.1799163179916318, 'fraction_numerical': 0.015595283377710156, 'mean_word_length': 2.9962006079027357, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4777430', 'n_tokens_mistral': 1637, 'n_tokens_neox': 1524, 'n_words': 642}