diff options
-rw-r--r-- | src/value.cc | 59 | ||||
-rw-r--r-- | testdata/scad/misc/vector-values.scad | 40 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 3 | ||||
-rw-r--r-- | tests/regression/echotest/vector-values-expected.txt | 10 |
4 files changed, 111 insertions, 1 deletions
diff --git a/src/value.cc b/src/value.cc index 47fac1e..48fea1a 100644 --- a/src/value.cc +++ b/src/value.cc @@ -30,6 +30,7 @@ #include <sstream> #include <QDir> #include <boost/foreach.hpp> +#include "printutils.h" Value::Value() { @@ -157,6 +158,64 @@ Value Value::operator * (const Value &v) const if (this->type == NUMBER && v.type == NUMBER) { return Value(this->num * v.num); } + if (this->type == VECTOR && v.type == VECTOR && this->vec.size() == v.vec.size() ) { + if ( this->vec[0]->type == NUMBER && v.vec[0]->type == NUMBER ) { + // Vector dot product. + double r=0.0; + for (size_t i=0; i <this->vec.size(); i++) { + if ( this->vec[i]->type != NUMBER || v.vec[i]->type != NUMBER ) return Value(); + r = r + (this->vec[i]->num * v.vec[i]->num); + } + return Value(r); + } else if ( this->vec[0]->type == VECTOR && v.vec[0]->type == NUMBER ) { + // Matrix * Vector + Value r; + r.type = VECTOR; + for ( size_t i=0; i < this->vec.size(); i++) { + double r_e=0.0; + if ( this->vec[i]->vec.size() != v.vec.size() ) return Value(); + for ( size_t j=0; j < this->vec[i]->vec.size(); j++) { + if ( this->vec[i]->vec[j]->type != NUMBER || v.vec[i]->type != NUMBER ) return Value(); + r_e = r_e + (this->vec[i]->vec[j]->num * v.vec[j]->num); + } + r.vec.push_back(new Value(r_e)); + } + return r; + } else if (this->vec[0]->type == NUMBER && v.vec[0]->type == VECTOR ) { + // Vector * Matrix + Value r; + r.type = VECTOR; + for ( size_t i=0; i < v.vec[0]->vec.size(); i++) { + double r_e=0.0; + for ( size_t j=0; j < v.vec.size(); j++) { + if ( v.vec[j]->vec.size() != v.vec[0]->vec.size() ) return Value(); + if ( this->vec[j]->type != NUMBER || v.vec[j]->vec[i]->type != NUMBER ) return Value(); + r_e = r_e + (this->vec[j]->num * v.vec[j]->vec[i]->num); + } + r.vec.push_back(new Value(r_e)); + } + return r; + } + } + if (this->type == VECTOR && v.type == VECTOR && this->vec[0]->type == VECTOR && v.vec[0]->type == VECTOR && this->vec[0]->vec.size() == v.vec.size() ) { + // Matrix * Matrix + Value rrow; + rrow.type = VECTOR; + for ( size_t i=0; i < this->vec.size(); i++ ) { + Value * rcol=new Value(); + rcol->type = VECTOR; + for ( size_t j=0; j < this->vec.size(); j++ ) { + double r_e=0.0; + for ( size_t k=0; k < v.vec.size(); k++ ) { + r_e = r_e + (this->vec[i]->vec[k]->num * v.vec[k]->vec[j]->num); + } + // PRINTB(" r_e = %s",r_e); + rcol->vec.push_back(new Value(r_e)); + } + rrow.vec.push_back(rcol); + } + return rrow; + } return Value(); } diff --git a/testdata/scad/misc/vector-values.scad b/testdata/scad/misc/vector-values.scad new file mode 100644 index 0000000..1872b39 --- /dev/null +++ b/testdata/scad/misc/vector-values.scad @@ -0,0 +1,40 @@ +// Value vector tests. + +a1=[0,1,2]; +b1=[3,4,5]; +c1=a1*b1; +echo(str("Testing vector dot product: ",c1)); + +d1=[1,0]; +echo(str(" Bounds check: ",a1*d1)); + +m2=[[0,1],[1,0]]; +v2=[2,3]; +p2=m2*v2; +echo(str("Testing matrix * vector: ",p2)); + +d2=[0,0,1]; +echo(str(" Bounds check: ",m2*d2)); + +m3=[[1,-1,1],[1,0,-1]]; +v3=[1,1]; +p3=v3*m3; +echo(str("Testing vector * matrix: ",p3)); + +echo(str(" Bounds check: ",m3*v3)); + +ma4=[ [1,0],[0,1] ]; +mb4=[ [1,0],[0,1] ]; +echo(str("Testing id matrix * id matrix: ",ma4*mb4)); + +ma5=[ [1, 0, 1] + ,[0, 1,-1] ]; +mb5=[ [1,0] + ,[0,1] + ,[1,1] ]; +echo(str("Testing asymmetric matrix * matrix: ",ma5*mb5)); +echo(str("Testing alternate asymmetric matrix * matrix: ",mb5*ma5)); + +echo(str(" Bounds check: ",ma5*ma4)); + +cube(1.0); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b81ce8c..4329795 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -608,7 +608,8 @@ list(APPEND ECHO_FILES ${FUNCTION_FILES} ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/builtin-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/dim-all.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/string-test.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/string-indexing.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/string-indexing.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/vector-values.scad) list(APPEND DUMPTEST_FILES ${MINIMAL_FILES} ${FEATURES_FILES} ${EXAMPLE_FILES}) list(APPEND DUMPTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/escape-test.scad diff --git a/tests/regression/echotest/vector-values-expected.txt b/tests/regression/echotest/vector-values-expected.txt new file mode 100644 index 0000000..7654892 --- /dev/null +++ b/tests/regression/echotest/vector-values-expected.txt @@ -0,0 +1,10 @@ +ECHO: "Testing vector dot product: 14" +ECHO: " Bounds check: undef" +ECHO: "Testing matrix * vector: [3, 2]" +ECHO: " Bounds check: undef" +ECHO: "Testing vector * matrix: [2, -1, 0]" +ECHO: " Bounds check: undef" +ECHO: "Testing id matrix * id matrix: [[1, 0], [0, 1]]" +ECHO: "Testing asymmetric matrix * matrix: [[2, 1], [-1, 0]]" +ECHO: "Testing alternate asymmetric matrix * matrix: [[1, 0, 1], [0, 1, -1], [1, 1, 0]]" +ECHO: " Bounds check: undef" |