mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-08-21 09:21:21 +02:00
Fix bug in skin, add some complex stuff to math and tests
This commit is contained in:
114
math.scad
114
math.scad
@@ -1465,19 +1465,52 @@ function deriv3(data, h=1, closed=false) =
|
||||
|
||||
// Section: Complex Numbers
|
||||
|
||||
|
||||
// Function: complex()
|
||||
// Usage:
|
||||
// z = complex(list)
|
||||
// Description:
|
||||
// Converts a real valued number, vector or matrix into its complex analog
|
||||
// by replacing all entries with a 2-vector that has zero imaginary part.
|
||||
function complex(list) =
|
||||
is_num(list) ? [list,0] :
|
||||
[for(entry=list) is_num(entry) ? [entry,0] : complex(entry)];
|
||||
|
||||
|
||||
// Function: c_mul()
|
||||
// Usage:
|
||||
// c = c_mul(z1,z2)
|
||||
// Description:
|
||||
// Multiplies two complex numbers represented by 2D vectors.
|
||||
// Returns a complex number as a 2D vector [REAL, IMAGINARY].
|
||||
// Multiplies two complex numbers, vectors or matrices, where complex numbers
|
||||
// or entries are represented as vectors: [REAL, IMAGINARY]. Note that all
|
||||
// entries in both arguments must be complex.
|
||||
// Arguments:
|
||||
// z1 = First complex number, given as a 2D vector [REAL, IMAGINARY]
|
||||
// z2 = Second complex number, given as a 2D vector [REAL, IMAGINARY]
|
||||
function c_mul(z1,z2) =
|
||||
assert( is_matrix([z1,z2],2,2), "Complex numbers should be represented by 2D vectors" )
|
||||
// z1 = First complex number, vector or matrix
|
||||
// z2 = Second complex number, vector or matrix
|
||||
|
||||
function _split_complex(data) =
|
||||
is_vector(data,2) ? data
|
||||
: is_num(data[0][0]) ? [data*[1,0], data*[0,1]]
|
||||
: [
|
||||
[for(vec=data) vec * [1,0]],
|
||||
[for(vec=data) vec * [0,1]]
|
||||
];
|
||||
|
||||
function _combine_complex(data) =
|
||||
is_vector(data,2) ? data
|
||||
: is_num(data[0][0]) ? [for(i=[0:len(data[0])-1]) [data[0][i],data[1][i]]]
|
||||
: [for(i=[0:1:len(data[0])-1])
|
||||
[for(j=[0:1:len(data[0][0])-1])
|
||||
[data[0][i][j], data[1][i][j]]]];
|
||||
|
||||
function _c_mul(z1,z2) =
|
||||
[ z1.x*z2.x - z1.y*z2.y, z1.x*z2.y + z1.y*z2.x ];
|
||||
|
||||
function c_mul(z1,z2) =
|
||||
is_matrix([z1,z2],2,2) ? _c_mul(z1,z2) :
|
||||
_combine_complex(_c_mul(_split_complex(z1), _split_complex(z2)));
|
||||
|
||||
|
||||
// Function: c_div()
|
||||
// Usage:
|
||||
// x = c_div(z1,z2)
|
||||
@@ -1493,7 +1526,52 @@ function c_div(z1,z2) =
|
||||
let(den = z2.x*z2.x + z2.y*z2.y)
|
||||
[(z1.x*z2.x + z1.y*z2.y)/den, (z1.y*z2.x - z1.x*z2.y)/den];
|
||||
|
||||
// For the sake of consistence with Q_mul and vmul, c_mul should be called C_mul
|
||||
|
||||
// Function: c_conj()
|
||||
// Usage:
|
||||
// w = c_conj(z)
|
||||
// Description:
|
||||
// Computes the complex conjugate of the input, which can be a complex number,
|
||||
// complex vector or complex matrix.
|
||||
function c_conj(z) =
|
||||
is_vector(z,2) ? [z.x,-z.y] :
|
||||
[for(entry=z) c_conj(entry)];
|
||||
|
||||
// Function: c_real()
|
||||
// Usage:
|
||||
// x = c_real(z)
|
||||
// Description:
|
||||
// Returns real part of a complex number, vector or matrix.
|
||||
function c_real(z) =
|
||||
is_vector(z,2) ? z.x
|
||||
: is_num(z[0][0]) ? z*[1,0]
|
||||
: [for(vec=z) vec * [1,0]];
|
||||
|
||||
// Function: c_imag()
|
||||
// Usage:
|
||||
// x = c_imag(z)
|
||||
// Description:
|
||||
// Returns imaginary part of a complex number, vector or matrix.
|
||||
function c_imag(z) =
|
||||
is_vector(z,2) ? z.y
|
||||
: is_num(z[0][0]) ? z*[0,1]
|
||||
: [for(vec=z) vec * [0,1]];
|
||||
|
||||
|
||||
// Function: c_ident()
|
||||
// Usage:
|
||||
// I = c_ident(n)
|
||||
// Description:
|
||||
// Produce an n by n complex identity matrix
|
||||
function c_ident(n) = [for (i = [0:1:n-1]) [for (j = [0:1:n-1]) (i==j)?[1,0]:[0,0]]];
|
||||
|
||||
// Function: c_norm()
|
||||
// Usage:
|
||||
// n = c_norm(z)
|
||||
// Description:
|
||||
// Compute the norm of a complex number or vector.
|
||||
function c_norm(z) = norm_fro(z);
|
||||
|
||||
|
||||
// Section: Polynomials
|
||||
|
||||
@@ -1539,12 +1617,12 @@ function quadratic_roots(a,b,c,real=false) =
|
||||
// where a_n is the z^n coefficient. Polynomial coefficients are real.
|
||||
// The result is a number if `z` is a number and a complex number otherwise.
|
||||
function polynomial(p,z,k,total) =
|
||||
is_undef(k)
|
||||
? assert( is_vector(p) , "Input polynomial coefficients must be a vector." )
|
||||
assert( is_finite(z) || is_vector(z,2), "The value of `z` must be a real or a complex number." )
|
||||
polynomial( _poly_trim(p), z, 0, is_num(z) ? 0 : [0,0])
|
||||
: k==len(p) ? total
|
||||
: polynomial(p,z,k+1, is_num(z) ? total*z+p[k] : c_mul(total,z)+[p[k],0]);
|
||||
is_undef(k)
|
||||
? assert( is_vector(p) , "Input polynomial coefficients must be a vector." )
|
||||
assert( is_finite(z) || is_vector(z,2), "The value of `z` must be a real or a complex number." )
|
||||
polynomial( _poly_trim(p), z, 0, is_num(z) ? 0 : [0,0])
|
||||
: k==len(p) ? total
|
||||
: polynomial(p,z,k+1, is_num(z) ? total*z+p[k] : c_mul(total,z)+[p[k],0]);
|
||||
|
||||
// Function: poly_mult()
|
||||
// Usage:
|
||||
@@ -1554,12 +1632,12 @@ function polynomial(p,z,k,total) =
|
||||
// Given a list of polynomials represented as real coefficient lists, with the highest degree coefficient first,
|
||||
// computes the coefficient list of the product polynomial.
|
||||
function poly_mult(p,q) =
|
||||
is_undef(q) ?
|
||||
len(p)==2
|
||||
is_undef(q) ?
|
||||
len(p)==2
|
||||
? poly_mult(p[0],p[1])
|
||||
: poly_mult(p[0], poly_mult(select(p,1,-1)))
|
||||
:
|
||||
assert( is_vector(p) && is_vector(q),"Invalid arguments to poly_mult")
|
||||
: poly_mult(p[0], poly_mult(select(p,1,-1)))
|
||||
:
|
||||
assert( is_vector(p) && is_vector(q),"Invalid arguments to poly_mult")
|
||||
p*p==0 || q*q==0
|
||||
? [0]
|
||||
: _poly_trim(convolve(p,q));
|
||||
|
Reference in New Issue
Block a user