Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ MANIFEST
*.DS_Store
.venv
.hypothesis
venv/
33 changes: 33 additions & 0 deletions src/flint/types/qqbar.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from flint.flintlib.types.flint cimport slong
from flint.flintlib.functions.fmpz cimport fmpz_t
from flint.flintlib.functions.fmpq cimport fmpq_t

cdef extern from "flint/qqbar.h" nogil:
ctypedef struct qqbar_struct:
pass
ctypedef qqbar_struct qqbar_t[1]

# Lifecycle methods
void qqbar_init(qqbar_t res)
void qqbar_clear(qqbar_t res)
void qqbar_set(qqbar_t res, const qqbar_t x)
void qqbar_set_si(qqbar_t res, slong x)

# Printing methods
void qqbar_print(const qqbar_t x)
void qqbar_printn(const qqbar_t x, slong n)

# Interoperability setters
void qqbar_set_fmpz(qqbar_t res, const fmpz_t x)
void qqbar_set_fmpq(qqbar_t res, const fmpq_t x)

# Arithmetic operations
void qqbar_add(qqbar_t res, const qqbar_t x, const qqbar_t y)
void qqbar_sub(qqbar_t res, const qqbar_t x, const qqbar_t y)
void qqbar_mul(qqbar_t res, const qqbar_t x, const qqbar_t y)
void qqbar_div(qqbar_t res, const qqbar_t x, const qqbar_t y)

from flint.flint_base.flint_base cimport flint_scalar

cdef class qqbar(flint_scalar):
cdef qqbar_t val
99 changes: 99 additions & 0 deletions src/flint/types/qqbar.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from flint.flintlib.functions.qqbar cimport (
qqbar_init,
qqbar_clear,
qqbar_set,
qqbar_set_si,
qqbar_printn,
qqbar_set_fmpz,
qqbar_set_fmpq,
qqbar_add,
qqbar_sub,
qqbar_mul,
qqbar_div
)
from flint.types.fmpz cimport fmpz
from flint.types.fmpq cimport fmpq

cdef class qqbar(flint_scalar):
"""
The qqbar class represents algebraic numbers.
"""

def __cinit__(self):
qqbar_init(self.val)

def __dealloc__(self):
qqbar_clear(self.val)

def __init__(self, val=None):
if val is not None:
if isinstance(val, qqbar):
qqbar_set(self.val, (<qqbar>val).val)
elif isinstance(val, int):
qqbar_set_si(self.val, val)
elif isinstance(val, fmpz):
qqbar_set_fmpz(self.val, (<fmpz>val).val)
elif isinstance(val, fmpq):
qqbar_set_fmpq(self.val, (<fmpq>val).val)
else:
raise TypeError("Cannot initialize qqbar type from input")

def str(self, Py_ssize_t digits=15):
"""
Converts the algebraic number to a decimal string representation by capturing C-level stdout.
"""
import os
import sys

cdef int stdout_fd = 1
cdef int saved_stdout = os.dup(stdout_fd)

pipe_read, pipe_write = os.pipe()
os.dup2(pipe_write, stdout_fd)

try:
qqbar_printn(self.val, digits)
sys.stdout.flush()
finally:
os.close(pipe_write)
os.dup2(saved_stdout, stdout_fd)
os.close(saved_stdout)

cdef bytes captured = os.read(pipe_read, 4096)
os.close(pipe_read)

return captured.decode('utf-8').strip()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is some weird AI stuff. There is no way that the os module should be involved here.


def __str__(self):
return self.str()

def __repr__(self):
return f"qqbar({self.str()})"

def __add__(x, y):
cdef qqbar res = qqbar()
cdef qqbar c_x = x if isinstance(x, qqbar) else qqbar(x)
cdef qqbar c_y = y if isinstance(y, qqbar) else qqbar(y)
qqbar_add(res.val, c_x.val, c_y.val)
return res

def __sub__(x, y):
cdef qqbar res = qqbar()
cdef qqbar c_x = x if isinstance(x, qqbar) else qqbar(x)
cdef qqbar c_y = y if isinstance(y, qqbar) else qqbar(y)
qqbar_sub(res.val, c_x.val, c_y.val)
return res

def __mul__(x, y):
cdef qqbar res = qqbar()
cdef qqbar c_x = x if isinstance(x, qqbar) else qqbar(x)
cdef qqbar c_y = y if isinstance(y, qqbar) else qqbar(y)
qqbar_mul(res.val, c_x.val, c_y.val)
return res

def __truediv__(x, y):
cdef qqbar res = qqbar()
cdef qqbar c_x = x if isinstance(x, qqbar) else qqbar(x)
cdef qqbar c_y = y if isinstance(y, qqbar) else qqbar(y)
qqbar_div(res.val, c_x.val, c_y.val)
return res