rssn 0.2.9

A comprehensive scientific computing library for Rust, aiming for feature parity with NumPy and SymPy.
Documentation
//! JSON-based FFI API for numerical multi-valued functions.

use std::os::raw::c_char;

use num_complex::Complex;
use serde::Deserialize;
use serde::Serialize;

use crate::ffi_apis::common::from_json_string;
use crate::ffi_apis::common::to_c_string;
use crate::ffi_apis::ffi_api::FfiResult;
use crate::numerical::multi_valued;
use crate::symbolic::core::Expr;

#[derive(Deserialize)]
struct NewtonInput {
    f: Expr,
    f_prime: Expr,
    start_re: f64,
    start_im: f64,
    tolerance: f64,
    max_iter: usize,
}

#[derive(Serialize)]
struct ComplexResult {
    re: f64,
    im: f64,
}

/// Newton's method for complex roots using JSON for FFI communication.
///
/// # Arguments
/// * `input_json` - JSON-encoded `NewtonInput`.
///
/// # Returns
/// JSON-encoded `FfiResult<ComplexResult, String>`.
///
/// # Safety
///
/// This function is unsafe because it dereferences raw pointers as part of the FFI boundary.
/// The caller must ensure:
/// 1. All pointer arguments are valid and point to initialized memory.
/// 2. The memory layout of passed structures matches the expected C-ABI layout.
/// 3. Any pointers returned by this function are managed according to the API's ownership rules.
///
/// # Panics
///
/// This function may panic if the FFI input is malformed, null where not expected,
/// or if internal state synchronization fails (e.g., poisoned locks).
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rssn_num_mv_newton_method_complex_json(
    input_json: *const c_char
) -> *mut c_char {
    let input: NewtonInput = match from_json_string(input_json) {
        | Some(i) => i,
        | None => {
            return to_c_string(
                serde_json::to_string(&FfiResult::<ComplexResult, String> {
                    ok: None,
                    err: Some("Invalid JSON input".to_string()),
                })
                .unwrap(),
            );
        },
    };

    let start_point = Complex::new(input.start_re, input.start_im);

    match multi_valued::newton_method_complex(
        &input.f,
        &input.f_prime,
        start_point,
        input.tolerance,
        input.max_iter,
    ) {
        | Some(root) => {
            let res = ComplexResult {
                re: root.re,
                im: root.im,
            };

            to_c_string(
                serde_json::to_string(&FfiResult {
                    ok: Some(res),
                    err: None::<String>,
                })
                .unwrap(),
            )
        },
        | None => {
            to_c_string(
                serde_json::to_string(&FfiResult::<ComplexResult, String> {
                    ok: None,
                    err: Some("Newton's method failed to converge".to_string()),
                })
                .unwrap(),
            )
        },
    }
}

#[derive(Deserialize)]
struct LogSqrtInput {
    re: f64,
    im: f64,
    k: i32,
}

/// Computes the k-th branch of the complex logarithm using JSON.
///
/// # Arguments
/// * `json` - JSON-encoded `LogSqrtInput`.
///
/// # Returns
/// JSON-encoded `FfiResult<ComplexResult, String>`.
///
/// # Safety
///
/// This function is unsafe because it dereferences raw pointers as part of the FFI boundary.
/// The caller must ensure:
/// 1. All pointer arguments are valid and point to initialized memory.
/// 2. The memory layout of passed structures matches the expected C-ABI layout.
/// 3. Any pointers returned by this function are managed according to the API's ownership rules.
///
/// # Panics
///
/// This function may panic if the FFI input is malformed, null where not expected,
/// or if internal state synchronization fails (e.g., poisoned locks).
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rssn_num_mv_complex_log_k_json(json: *const c_char) -> *mut c_char {
    let input: LogSqrtInput = match from_json_string(json) {
        | Some(i) => i,
        | None => {
            return to_c_string(
                serde_json::to_string(&FfiResult::<ComplexResult, String> {
                    ok: None,
                    err: Some("Invalid JSON input".to_string()),
                })
                .unwrap(),
            );
        },
    };

    let z = Complex::new(input.re, input.im);

    let res = multi_valued::complex_log_k(z, input.k);

    let out = ComplexResult {
        re: res.re,
        im: res.im,
    };

    to_c_string(
        serde_json::to_string(&FfiResult {
            ok: Some(out),
            err: None::<String>,
        })
        .unwrap(),
    )
}

/// Computes the k-th branch of the complex square root using JSON.
///
/// # Arguments
/// * `json` - JSON-encoded `LogSqrtInput`.
///
/// # Returns
/// JSON-encoded `FfiResult<ComplexResult, String>`.
///
/// # Safety
///
/// This function is unsafe because it dereferences raw pointers as part of the FFI boundary.
/// The caller must ensure:
/// 1. All pointer arguments are valid and point to initialized memory.
/// 2. The memory layout of passed structures matches the expected C-ABI layout.
/// 3. Any pointers returned by this function are managed according to the API's ownership rules.
///
/// # Panics
///
/// This function may panic if the FFI input is malformed, null where not expected,
/// or if internal state synchronization fails (e.g., poisoned locks).
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rssn_num_mv_complex_sqrt_k_json(json: *const c_char) -> *mut c_char {
    let input: LogSqrtInput = match from_json_string(json) {
        | Some(i) => i,
        | None => {
            return to_c_string(
                serde_json::to_string(&FfiResult::<ComplexResult, String> {
                    ok: None,
                    err: Some("Invalid JSON input".to_string()),
                })
                .unwrap(),
            );
        },
    };

    let z = Complex::new(input.re, input.im);

    let res = multi_valued::complex_sqrt_k(z, input.k);

    let out = ComplexResult {
        re: res.re,
        im: res.im,
    };

    to_c_string(
        serde_json::to_string(&FfiResult {
            ok: Some(out),
            err: None::<String>,
        })
        .unwrap(),
    )
}

#[derive(Deserialize)]
struct PowInput {
    z_re: f64,
    z_im: f64,
    w_re: f64,
    w_im: f64,
    k: i32,
}

/// Computes the k-th branch of complex power using JSON.
///
/// # Arguments
/// * `json` - JSON-encoded `PowInput`.
///
/// # Returns
/// JSON-encoded `FfiResult<ComplexResult, String>`.
///
/// # Safety
///
/// This function is unsafe because it dereferences raw pointers as part of the FFI boundary.
/// The caller must ensure:
/// 1. All pointer arguments are valid and point to initialized memory.
/// 2. The memory layout of passed structures matches the expected C-ABI layout.
/// 3. Any pointers returned by this function are managed according to the API's ownership rules.
///
/// # Panics
///
/// This function may panic if the FFI input is malformed, null where not expected,
/// or if internal state synchronization fails (e.g., poisoned locks).
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rssn_num_mv_complex_pow_k_json(json: *const c_char) -> *mut c_char {
    let input: PowInput = match from_json_string(json) {
        | Some(i) => i,
        | None => {
            return to_c_string(
                serde_json::to_string(&FfiResult::<ComplexResult, String> {
                    ok: None,
                    err: Some("Invalid JSON input".to_string()),
                })
                .unwrap(),
            );
        },
    };

    let z = Complex::new(input.z_re, input.z_im);

    let w = Complex::new(input.w_re, input.w_im);

    let res = multi_valued::complex_pow_k(z, w, input.k);

    let out = ComplexResult {
        re: res.re,
        im: res.im,
    };

    to_c_string(
        serde_json::to_string(&FfiResult {
            ok: Some(out),
            err: None::<String>,
        })
        .unwrap(),
    )
}