Hi,
I am playing around with calling routines from a C library (FFTW3) and wrote the following code that does precisely what it should. The fftw_plan_dft_1d
needs the address of the input and output array. II achieve this by passing a reference to the 0-th element (&(data.items[0])
). The compiler goes with it, but it feels a little bit dirty. Is there a cleaner way? And are there more things I could improve? (Still relatively new to zig)
Thank you for your Help.
The code:
main.zig
:
const std = @import("std");
const stdout = std.io.getStdOut().writer();
const fftw = @cImport(@cInclude("fftw3.h"));
const ArrayList = std.ArrayList;
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
fn print_array(array: ArrayList(fftw.fftw_complex)) !void {
for (array.items) |r| {
try stdout.print("({0d:5.2}, {1d:5.2}) ", .{ r[0], r[1] });
}
try stdout.print("\n", .{});
}
pub fn main() !void {
const size = 8;
var data = try ArrayList(fftw.fftw_complex).initCapacity(allocator, size);
defer data.deinit();
var ftdata = try ArrayList(fftw.fftw_complex).initCapacity(allocator, size);
defer ftdata.deinit();
for (0..(size / 2)) |_| {
_ = try data.append(.{ 1.0, 0.0 });
_ = try ftdata.append(.{ 0.0, 0.0 });
}
for ((size / 2)..size) |_| {
_ = try data.append(.{ 0.0, 0.0 });
_ = try ftdata.append(.{ 0.0, 0.0 });
}
try print_array(data);
try print_array(ftdata);
try stdout.print("\n", .{});
const plan_fw = fftw.fftw_plan_dft_1d(size, &(data.items[0]), &(ftdata.items[0]), fftw.FFTW_FORWARD, fftw.FFTW_ESTIMATE);
defer fftw.fftw_destroy_plan(plan_fw);
fftw.fftw_execute(plan_fw);
try print_array(data);
try print_array(ftdata);
try stdout.print("\n", .{});
for (data.items) |*r| {
r.* = .{ 0.0, 0.0 };
}
try print_array(data);
try print_array(ftdata);
try stdout.print("\n", .{});
const plan_bw = fftw.fftw_plan_dft_1d(size, &(ftdata.items[0]), &(data.items[0]), fftw.FFTW_BACKWARD, fftw.FFTW_ESTIMATE);
defer fftw.fftw_destroy_plan(plan_bw);
fftw.fftw_execute(plan_bw);
try print_array(data);
try print_array(ftdata);
}
build.zig
:
const std = @import("std");
pub fn build(b: *std.Build) void {
const exe = b.addExecutable(.{
.name = "fft.x",
.root_source_file = b.path("main.zig"),
.target = b.host,
});
exe.linkSystemLibrary2("fftw3", .{ .preferred_link_mode = .static });
exe.linkLibC();
b.installArtifact(exe);
const run_exe = b.addRunArtifact(exe);
const run_step = b.step("run", "Run the application");
run_step.dependOn(&run_exe.step);
}