-
-
Save ochafik/e1a439478cbaf211a8b326bde900440e to your computer and use it in GitHub Desktop.
Example C++ Transpiling of OpenSCAD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| function submatrix_set(M,A,m=0,n=0) = | |
| assert(is_list(M)) | |
| assert(is_list(A)) | |
| assert(is_int(m)) | |
| assert(is_int(n)) | |
| let( badrows = [for(i=idx(A)) if (!is_list(A[i])) i]) | |
| assert(badrows==[], str("Input submatrix malformed rows: ",badrows)) | |
| [for(i=[0:1:len(M)-1]) | |
| assert(is_list(M[i]), str("Row ",i," of input matrix is not a list")) | |
| [for(j=[0:1:len(M[i])-1]) | |
| i>=m && i <len(A)+m && j>=n && j<len(A[0])+n ? A[i-m][j-n] : M[i][j]]]; | |
| function submatrix(M,idx1,idx2) = | |
| [for(i=idx1) [for(j=idx2) M[i][j] ] ]; | |
| function cholesky(A) = | |
| assert(is_matrix(A,square=true),"A must be a square matrix") | |
| assert(is_matrix_symmetric(A),"Cholesky factorization requires a symmetric matrix") | |
| _cholesky(A,ident(len(A)), len(A)); | |
| function _cholesky(A,L,n) = | |
| A[0][0]<0 ? undef : // Matrix not positive definite | |
| len(A) == 1 ? submatrix_set(L,[[sqrt(A[0][0])]], n-1,n-1): | |
| let( | |
| i = n+1-len(A) | |
| ) | |
| let( | |
| sqrtAii = sqrt(A[0][0]), | |
| Lnext = [for(j=[0:n-1]) | |
| [for(k=[0:n-1]) | |
| j<i-1 || k<i-1 ? (j==k ? 1 : 0) | |
| : j==i-1 && k==i-1 ? sqrtAii | |
| : j==i-1 ? 0 | |
| : k==i-1 ? A[j-(i-1)][0]/sqrtAii | |
| : j==k ? 1 : 0]], | |
| Anext = submatrix(A,[1:n-1], [1:n-1]) - outer_product(list_tail(A[0]), list_tail(A[0]))/A[0][0] | |
| ) | |
| _cholesky(Anext,L*Lnext,n); | |
| */ | |
| #include <vector> | |
| #include <set> | |
| #include <variant> | |
| // #include <shared_ptr> | |
| namespace scad { | |
| using std::vector; | |
| using std::shared_ptr; | |
| using std::monostate; | |
| using std::pair; | |
| using std::string; | |
| using std::variant; | |
| using std::array; | |
| class Type : public std::enable_shared_from_this<Type> { | |
| virtual shared_ptr<Type> unionWith(const Type &type) const = 0; | |
| virtual shared_ptr<Type> operator[](int index) const = 0; | |
| virtual bool operator==(const Type& other) const = 0; | |
| }; | |
| class ScalarType : public Type { | |
| enum { Undef, Bool, Int, Float, String } type; | |
| }; | |
| class FunctionType : public Type { | |
| using Signature = pair<Type, vector<pair<variant<monostate, string>, Type>>; | |
| shared_ptr<Signature> unified_signature; | |
| vector<shared_ptr<Signature>> traced_signatures; | |
| }; | |
| class AnyType : public Type { | |
| shared_ptr<Type> unionWith(const Type &type) const override { return this->shared_from_this(); }; | |
| }; | |
| class ConstantScalarType : public ScalarType { | |
| Value value; | |
| }; | |
| class UnionType : public Type { | |
| vector<shared_ptr<Type>> components; | |
| }; | |
| class TupleType : public Type { | |
| vector<shared_ptr<Type>> components; | |
| }; | |
| class CollectionType : public Type { | |
| shared_ptr<Type> element_type; | |
| static const int DYNAMIC = -1; | |
| vector<int> shape; | |
| }; | |
| struct Shape { | |
| enum { Undef, Bool, Int, Float, String, Vector, Matrix } element_type; | |
| }; | |
| struct Type { | |
| enum { | |
| Undef, Bool, Int, Float, String, Vector, Matrix | |
| } type; | |
| }; | |
| using StaticMatrix = std::variant<Eigen::MatrixX, DynamicMatrix>; | |
| using DynamicMatrix = std::variant<Eigen::MatrixXd, >; | |
| using Matrix = std::variant<StaticMatrix, DynamicMatrix>; | |
| class Matrix { | |
| public: | |
| }; | |
| using Value = std::variant<std:monostate, int64_t, double, std::string, Eigen::Matrix, std::vector<Value>>; | |
| // #define IS_TYPE_PREDICATE(type_name, type) | |
| template <class T> bool is_int(const T& v) { return false; } | |
| template <> bool is_int(const int& v) { return true; } | |
| template <> bool is_int(const Value& v) { return std::get<int>(&v); } | |
| template <class T> bool is_list(const T& v) { return false; } | |
| template <> bool is_list(const std::vector<Value>& v) { return true; } | |
| template <> bool is_list(const Matrix& v) { return true; } | |
| template <> bool is_list(const Value& v) { return std::get<Matrix>(&v); } | |
| template <class T> int len(const T& v) { return false; } | |
| template <> int len(const std::vector<Value>& v) { return v.size(); } | |
| template <> template <int N, int M, class T, bool is_transposed> | |
| int len(const Matrix<T, N, M, is_transposed>& v) { | |
| return is_transposed ? v.cols() : v.rows(); | |
| } | |
| template <class T, int N, int M, bool is_transposed> | |
| struct matrix_traits { | |
| // typedef void type; | |
| }; | |
| template <class T, int N> | |
| typename matrix_traits<T, N, 1, /* is_transposed= */ true>::type matrix(const array<T, N>& vs) { | |
| typename matrix_traits<T, N, 1, /* is_transposed= */ true>::type ret; | |
| for (auto i = 0; i < N; i++) { | |
| ret[0][i] = vs[i]; | |
| } | |
| return ret; | |
| } | |
| template <class T, int N, int M> | |
| typename matrix_traits<T, N, M, /* is_transposed= */ false>::type matrix(const array<array<T, M>, N>& vs) { | |
| typename matrix_traits<T, N, M, /* is_transposed= */ false>::type ret; | |
| for (auto i = 0; i < N; i++) { | |
| for (auto j = 0; j < M; i++) { | |
| ret[i][j] = vs[i][j]; | |
| } | |
| return ret; | |
| } | |
| }; // namespace scad | |
| template <class M_, class A_, class R> | |
| R submatrix_set(M_ M, A_ A, int m = 0, int n = 0) { | |
| assert(is_list_(M)); | |
| assert(is_list_(A)); | |
| assert(is_int(m)); | |
| assert(is_int(n)); | |
| auto badrows = scad::list_for(idx(A), [&](auto i) { return !is_list(A[i]); }, [&](auto i) { return i; }); | |
| assert(badrows==[], str("Input submatrix malformed rows: ",badrows)) | |
| [for(i=[0:1:len(M)-1]) | |
| assert(is_list(M[i]), str("Row ",i," of input matrix is not a list")) | |
| [for(j=[0:1:len(M[i])-1]) | |
| i>=m && i <len(A)+m && j>=n && j<len(A[0])+n ? A[i-m][j-n] : M[i][j]]]; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment