UnsafeMutablePointer<Int8> from String in Swift - pointers

I'm using the dgeev algorithm from the LAPACK implementation in the Accelerate framework to calculate eigenvectors and eigenvalues of a matrix. Sadly the LAPACK functions are not described in the Apple Documentation with a mere link to http://netlib.org/lapack/faq.html included.
If you look it up, you will find that the first two arguments in dgeev are characters signifying whether to calculate eigenvectors or not. In Swift, it is asking for UnsafeMutablePointer<Int8>. When I simply use "N", I get an error. The dgeev function and the error are described in the following screenshot
What should I do to solve this?

The "problem" is that the first two parameters are declared as char *
and not as const char *, even if the strings are not modified by the function:
int dgeev_(char *__jobvl, char *__jobvr, ...);
is mapped to Swift as
func dgeev_(__jobvl: UnsafeMutablePointer<Int8>, __jobvr: UnsafeMutablePointer<Int8>, ...) -> Int32;
A possible workaround is
let result = "N".withCString {
dgeev_(UnsafeMutablePointer($0), UnsafeMutablePointer($0), &N, ...)
}
Inside the block, $0 is a pointer to a NUL-terminated array of char with the
UTF-8 representation of the string.
Remark: dgeev_() does not modify the strings pointed to by the first two arguments,
so it "should be" declared as
int dgeev_(const char *__jobvl, const char *__jobvr, ...);
which would be mapped to Swift as
func dgeev_(__jobvl: UnsafePointer<Int8>, __jobvr: UnsafePointer<Int8>, ...) -> Int32;
and in that case you could simply call it as
let result = dgeev_("N", "N", &N, ...)
because Swift strings are converted to UnsafePointer<Int8>) automatically,
as explained in String value to UnsafePointer<UInt8> function parameter behavior.

It is ugly, but you can use:
let unsafePointerOfN = ("N" as NSString).UTF8String
var unsafeMutablePointerOfN: UnsafeMutablePointer<Int8> = UnsafeMutablePointer(unsafePointerOfN)
and use unsafeMutablePointerOfN as a parameter instead of "N".

With Swift 4.2 and 5 you can use this similar approach
let str = "string"
let unsafePointer = UnsafeMutablePointer<Int8>(mutating: (str as NSString).utf8String)
You can get the result from unsafePointer.

Related

Can a julia struct be defined with persistent requirements on field dimensions?

If I define a new struct as
mutable struct myStruct
data::AbstractMatrix
labels::Vector{String}
end
and I want to throw an error if the length of labels is not equal to the number of columns of data, I know that I can write a constructor that enforces this condition like
myStruct(data, labels) = length(labels) != size(data)[2] ? error("Labels incorrect length") : new(data,labels)
However, once the struct is initialized, the labels field can be set to the incorrect length:
m = myStruct(randn(2,2), ["a", "b"])
m.labels = ["a"]
Is there a way to throw an error if the labels field is ever set to length not equal to the number of columns in data?
You could use StaticArrays.jl to fix the matrix and vector's sizes to begin with:
using StaticArrays
mutable struct MatVec{R, C, RC, VT, MT}
data::MMatrix{R, C, MT, RC} # RC should be R*C
labels::MVector{C, VT}
end
but there's the downside of having to compile for every concrete type with a unique permutation of type parameters R,C,MT,VT. StaticArrays also does not scale as well as normal Arrays.
If you don't restrict dimensions in the type parameters (with all those downsides) and want to throw an error at runtime, you got good and bad news.
The good news is you can control whatever mutation happens to your type. m.labels = v would call the method setproperty!(object::myStruct, name::Symbol, v), which you can define with all the safeguards you like.
The bad news is that you can't control mutation to the fields' types. push!(m.labels, 1) mutates in the push!(a::Vector{T}, item) method. The myStruct instance itself doesn't actually change; it still points to the same Vector. If you can't guarantee that you won't do something like x = m.labels; push!(x, "whoops") , then you really do need runtime checks, like iscorrect(m::myStruct) = length(m.labels) == size(m.data)[2]
A good option is to not access the fields of your struct directly. Instead, do it using a function. Eg:
mutable struct MyStruct
data::AbstractMatrix
labels::Vector{String}
end
function modify_labels(s::MyStruct, new_labels::Vector{String})
# do all checks and modifications
end
You should check chapter 8 from "Hands-On Design Patterns and Best Practices with Julia: Proven solutions to common problems in software design for Julia 1.x"

How to set a default value for a SEXP parameter in Rcpp

I have a Rcpp function that has an optional argument which is the maturity of a financial instrument. This can be given as a string (e.g. "2y") or as a integer. If no value is given, the function needs to use a default integer. How can I set the default value for that argument?
I have defined the function with a SEXP argument, the code tests if this is a string or not and depending on this transforms that maturity in an actual date in two different ways. However, I cannot set a default value for the SEXP argument. It seems like a basic question but I have googled quite a bit and could not find anything on this.
Date CPPConvertDate(Date ParamDate, SEXP MaturityDate = 1) {
Date Result ;
const int type_Matu = TYPEOF(MaturityDate) ;
if (type_Matu == 16){
std::string MaturityDate_string = as<std::string>(MaturityDate) ;
//' DO STUFF
} else {
int MaturityDate_int = as<int>(MaturityDate) ;
//' DO OTHER STUFF
}
return (Result) ;
}
Compiler tells me "Cannot initialize a parameter of type SEXP with an R value of type int" so it is pretty clear that I cannot use 1 a default value for MaturityDate. If possible I would like to avoid having two different functions, one with int arguments and one with string argument.
Listen to the compiler because it is a source of wisdown. SEXP has no assignment from 1 as it is a union type -- which is why we have all those wrap() functions to return a SEXP given all possible inputs.
So if it is a Date, use a date type. I have been doing that in RQuantLib (which after all lead to to Rcpp) for well over a decade. If you need a mixed type for different behaviour then methinks you will have a hard time coming up with a default value either way.
Also: not "RCPP". Rcpp, please.

How to chain tokio read functions?

Is there a way to chain the read_* functions in tokio::io in a "recursive" way ?
I'm essentially looking to do something like:
read_until x then read_exact y then write response then go back to the top.
In case you are confused what functions i'm talking about: https://docs.rs/tokio/0.1.11/tokio/io/index.html
Yes, there is a way.
read_until is returns a struct ReadUntil, which implements the Future-trait, which iteself provides a lot of useful functions, e.g. and_then which can be used to chain futures.
A simple (and silly) example looks like this:
extern crate futures;
extern crate tokio_io; // 0.1.8 // 0.1.24
use futures::future::Future;
use std::io::Cursor;
use tokio_io::io::{read_exact, read_until};
fn main() {
let cursor = Cursor::new(b"abcdef\ngh");
let mut buf = vec![0u8; 2];
println!(
"{:?}",
String::from_utf8_lossy(
read_until(cursor, b'\n', vec![])
.and_then(|r| read_exact(r.0, &mut buf))
.wait()
.unwrap()
.1
)
);
}
Here I use a Cursor, which happens to implement the AsyncRead-trait and use the read_until function to read until a newline occurs (between 'f' and 'g').
Afterwards to chain those I use and_then to use read_exact in case of an success, use wait to get the Result unwrap it (don't do this in production kids!) and take the second argument from the tuple (the first one is the cursor).
Last I convert the Vec into a String to display "gh" with println!.

How do I convert a vector of strings to a vector of integers in a functional way?

I'm trying to convert Vec<&str> to Vec<u16> but I can't figure out a functional way to do it.
let foo: &str = "1,2,3"; // Parsing a string here
let bar: Vec<&str> = foo.split(",").collect(); // Bar is a nice vector of &str's
I need to get bar into a Vec<u16>.
There's an iterator adapter map! You'd use it like this:
let bar: Vec<u16> = foo.split(",").map(|x| x.parse::<u16>().unwrap()).collect();
parse is a library function that relies on the trait FromStr, and it can return an error, so we need to unwrap() the error type. (This is a good idea for a short example, but in real code, you will want to handle the error properly - if you have a value that's not a u16 there, your program will just crash).
map takes a closure that takes it's parameter by value and then returns the iterator obtained by lazily applying that function. You're collecting all of the values here, but if you only take(5) of them, you would only parse 5 of the strings.
You haven't fully specified your problem. Specifically, what should happen when one of the strings cannot be parsed into a number? When you parse a number from a string using parse, it can fail. That is why the function returns a Result:
fn parse<F>(&self) -> Result<F, F::Err>
where
F: FromStr,
Here's a solution that takes the vector, gets an iterator with iter, changes each item using map and ultimately returns a Result using collect. If the parsing was a success, you get an Ok. If any failed, you get an Err:
fn main() {
let input = "1,2,3";
let strings: Vec<_> = input.split(",").collect();
let numbers: Result<Vec<u16>, _> = strings.iter().map(|x| x.parse()).collect();
println!("{:?}", numbers);
}
Or you could remove failed conversions by filtering out Err values with flat_map:
fn main() {
let input = "1,2,3";
let strings: Vec<_> = input.split(",").collect();
let numbers: Vec<u16> = strings.iter().flat_map(|x| x.parse()).collect();
println!("{:?}", numbers);
}
Of course, it's a bit silly to convert the string into a vector of strings and then convert it again to a vector of integers. If you actually have a comma-separated string and want numbers, do it in one go:
fn main() {
let input = "1,2,3";
let numbers: Result<Vec<u16>, _> = input.split(",").map(|x| x.parse()).collect();
println!("{:?}", numbers);
}
See also:
Why does `Option` support `IntoIterator`?
My take as someone not really experienced in Rust yet.
fn main() {
let foo: &str = "1,2,3"; // Parsing a string here
let bar: Vec<&str> = foo.split(",").collect(); // Bar is a nice vector of &str's
// here the magic happens
let baz = bar.iter().map(|x| x.parse::<i64>());
for x in baz {
match x {
Ok(i) => println!("{}", i),
Err(_) => println!("parse failed"),
}
}
}
Note that since parse returns a Result, you have to extract the value from each parsed element. You might want to behave in a different way, e.g. filter only the succeeded results.

Standard ML: Truncating String

I know ML has a bunch of string methods (substring, etc) that would make this easier but I want to get more comfortable with the language, so I'm implementing some myself.
I'm trying to truncate a string, i.e. cut off the string after a certain number of characters. I think I'm very close but am getting a syntax error when I do
val x::xs = explode(myString);
Here's the full code:
fun getAllButLast([x]) = nil
| getAllButLast(x::xs) = x::getAllButLast(xs);
fun truncate(myString, 0) = ""
| truncate(myString, limit:int) =
let
val x::xs = explode(myString);
in
x::truncate(implode(getAllButLast(xs)), limit - 1)
end;
Thoughts on why the compiler doesn't like this?
val x::xs = explode(myString);
Thanks for the help,
bclayman
Edit to include error:
Ullman.sml:82.5-82.55 Error: operator and operand don't agree [tycon mismatch]
operator domain: char * char list
operand: char * string
in expression:
x :: truncate (implode (getAllButLast <exp>),limit - 1)
uncaught exception Error
raised at: ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
../compiler/TopLevel/interact/evalloop.sml:44.55
../compiler/TopLevel/interact/evalloop.sml:292.17-292.20
As the error message shows, it is complaining about a different line. And it is complaining because the right operand of the :: operator in that line (the result of the recursive call to truncate) is a string, not a list. You probably want to use ^ instead, which denotes string concatenation.
Hint: There are other issues with your code. At least it is extremely inefficient. You should generally avoid implode/explode, but if you must use them, you should at least only call each of them once for the whole string, and not once for every character in the recursion.

Resources