aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/vasp/source/opvecs.cpp
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2009-04-01 21:13:09 +0000
committerThomas Grill <xovo@users.sourceforge.net>2009-04-01 21:13:09 +0000
commit0ed7a8b68dd73e2b0473b8127aeca99f3bac9061 (patch)
tree5c67818b38a5cc2f9caa5ca7f8640ca356adf02b /externals/grill/vasp/source/opvecs.cpp
parentbb4c7f6a245394d09dac9adfb2efb093d3d98452 (diff)
cleaned up grill externals - replaced with svn:externals to svn.grrrr.org/ext/trunk/
svn path=/trunk/; revision=10951
Diffstat (limited to 'externals/grill/vasp/source/opvecs.cpp')
-rw-r--r--externals/grill/vasp/source/opvecs.cpp631
1 files changed, 0 insertions, 631 deletions
diff --git a/externals/grill/vasp/source/opvecs.cpp b/externals/grill/vasp/source/opvecs.cpp
deleted file mode 100644
index f78210be..00000000
--- a/externals/grill/vasp/source/opvecs.cpp
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
-
-VASP modular - vector assembling signal processor / objects for Max/MSP and PD
-
-Copyright (c) 2002 Thomas Grill (xovo@gmx.net)
-For information on usage and redistribution, and for a DISCLAIMER OF ALL
-WARRANTIES, see the file, "license.txt," in this distribution.
-
-*/
-
-/*! \file vasp__ctrl.cpp
- \brief Methods for handling of vector data for real, complex and multi-vector cases.
-
-*/
-
-#include "main.h"
-#include "opbase.h"
-#include "classes.h"
-#include "vecblk.h"
-#include "util.h"
-
-/*! \brief Corrects for the common vector frame count
- \param frms frame count to correct
- \param bl new frame count
- \return true if a correction was made
-*/
-static BL corrlen(I &frms,I bl,I bf = -1,I bo = 0)
-{
- if(bf < 0) bf = bl;
-
- BL corr = false;
- BL all = frms < 0;
- if(all)
- frms = bl;
- else if(frms > bl) {
- // longer than vector length -> correct
- frms = bl;
- corr = true;
- }
-
- if(bo+frms > bf) {
- // now check if buffer size is exceeded
-// post("%s - %s vector (%s) exceeds buffer size: cropped",op,bli == 0?"src":"dst",bref->Name());
- frms = bf-bo;
- if(frms < 0) frms = 0;
- corr = true;
- }
-
- return corr;
-}
-
-
-inline BL corrlen(I &frms,VBuffer &b)
-{
- return corrlen(frms,b.Length(),b.Frames(),b.Offset());
-}
-
-
-/*! \brief Make real vector block for unary operations.
-
- \param op operation name
- \param src source vasp
- \param dst optional destination vasp
- \return struct with vector data
-
- \remark working size is maximum common vector size
-*/
-RVecBlock *VaspOp::GetRVecs(const C *op,CVasp &src,CVasp *dst)
-{
- I nvecs = src.Vectors();
- if(dst && dst->Ok() && dst->Vectors() != nvecs) {
- nvecs = min(nvecs,dst->Vectors());
- post("%s - src/dst vector number not equal -> taking minimum",op);
- }
-
- RVecBlock *ret = new RVecBlock(nvecs);
-
- BL ok = true,dlens = false;
- I tfrms = -1;
-
- Vasp *vbl[2] = {&src,dst};
-
- for(I bli = 0; bli < 2; ++bli)
- for(I ci = 0; ok && ci < nvecs; ++ci) {
- VBuffer *bref = NULL;
- if(vbl[bli] && vbl[bli]->Ok()) {
- bref = vbl[bli]->Buffer(ci);
- if(!bref->Data()) {
- post("%s - %s vector (%s) is invalid",op,bli == 0?"src":"dst",bref->Name());
- delete bref; bref = NULL;
- ok = false;
- }
- else
- dlens = dlens || corrlen(tfrms,*bref);
- }
-
- if(bli == 0)
- ret->Src(ci,bref);
- else
- ret->Dst(ci,bref);
- }
-
- if(dlens) post("%s - vector length has been limited to maximum common length (%i)",op,tfrms);
-
- ret->Frames(tfrms < 0?0:tfrms);
-
- if(ok) return ret;
- else { delete ret; return NULL; }
-}
-
-/*! \brief Make real vector block for unary operations.
-
- \param op operation name
- \param src source vasp
- \param dst optional destination vasp
- \param full true if imaginary part is compulsory
- \return struct with vector data
-*/
-CVecBlock *VaspOp::GetCVecs(const C *op,CVasp &src,CVasp *dst,BL full)
-{
- I nvecs = src.Vectors();
- if(dst && dst->Ok() && dst->Vectors() != nvecs) {
- nvecs = min(nvecs,dst->Vectors());
- post("%s - src/dst vector number not equal -> taking minimum",op);
- }
-
- I pairs = nvecs/2;
- if(nvecs != pairs*2)
- if(full) {
- post("%s - number of vectors is odd - not allowed",op);
- return NULL;
- }
- else {
- post("%s - number of vectors is odd - omitting last vector",op);
- }
-
- CVecBlock *ret = new CVecBlock(pairs);
- BL ok = true,dlens = false;
- I tfrms = -1;
-
- Vasp *vbl[2] = {&src,dst};
-
- for(I bli = 0; bli < 2; ++bli)
- for(I ci = 0; ci < pairs; ++ci) {
- VBuffer *bre = NULL,*bim = NULL; // complex channels
- if(vbl[bli] && vbl[bli]->Ok()) {
- const C *vnm = bli == 0?"src":"dst";
- bre = vbl[bli]->Buffer(ci*2);
- bim = vbl[bli]->Buffer(ci*2+1); // complex channels
-
- if(!bre->Data()) {
- post("%s - real %s vector (%s) is invalid",op,vnm,bre->Name());
- delete bre; bre = NULL;
- ok = false;
- }
- if(bim && !bim->Data()) {
- post("%s - imag %s vector (%s) is invalid",op,vnm,bim->Name());
- delete bim; bim = NULL;
- ok = false;
- }
-
- // check against common vector length
- if(bre) {
- dlens = dlens || corrlen(tfrms,*bre);
- }
- if(bim) {
- dlens = dlens || corrlen(tfrms,*bim);
- }
-
- }
-
- if(bli == 0)
- ret->Src(ci,bre,bim);
- else
- ret->Dst(ci,bre,bim);
- }
-
- if(dlens) post("%s - vector src/dst length has been limited to maximum common length (%i)",op,tfrms);
-
- ret->Frames(tfrms < 0?0:tfrms);
-
- if(ok) return ret;
- else { delete ret; return NULL; }
-}
-
-
-/*! \brief Make real vector block for binary operations.
-
- \param op operation name
- \param src source vasp
- \param arg argument vasp
- \param dst optional destination vasp
- \param multi 0 off/1 on/-1 auto... controls whether argument vector is single- or multi-vectored
- \return struct with vector data
-*/
-RVecBlock *VaspOp::GetRVecs(const C *op,CVasp &src,const CVasp &arg,CVasp *dst,I multi,BL ssize)
-{
- if(!arg.Ok()) {
- post("%s - invalid argument vasp detected and ignored",op);
- return NULL;
- }
-
- I nvecs = src.Vectors();
- if(dst && dst->Ok() && dst->Vectors() != nvecs) {
- nvecs = min(nvecs,dst->Vectors());
- post("%s - src/dst vector number not equal -> taking minimum",op);
- }
-
- RVecBlock *ret;
-
- if(multi < 0) { // auto mode
- multi = arg.Vectors() > 1;
- }
-
- if(multi) {
- if(arg.Vectors() < nvecs) {
- nvecs = arg.Vectors();
- post("%s - too few arg vectors, operating on only first %i vectors",op,nvecs);
- }
- ret = new RVecBlock(nvecs,nvecs,1);
- for(I i = 0; i < nvecs; ++i)
- ret->Arg(i,arg.Buffer(i));
- }
- else {
- if(arg.Vectors() > 1) {
- post("%s - using only first arg vector for all operations",op);
- }
- ret = new RVecBlock(nvecs,nvecs,1);
- for(I i = 0; i < nvecs; ++i)
- ret->Arg(i,arg.Buffer(0));
- }
-
- BL ok = true,dlens = false,dalens = false;
- I tfrms = -1,afrms = -1;
-
- for(I ci = 0; ok && ci < nvecs; ++ci) {
- VBuffer *bref = src.Buffer(ci);
- VBuffer *barg = ret->Arg(multi?ci:0);
- VBuffer *bdst = dst && dst->Ok()?dst->Buffer(ci):NULL;
-
- if(barg && (multi || ci == 0) && !barg->Data()) {
- post("%s - arg vector (%s) is invalid",op,barg->Name());
- ok = false; break; // really break?
- }
- else if(!bref->Data()) {
- post("%s - src vector (%s) is invalid",op,bref->Name());
- ok = false; break; // really break?
- }
-
- // check src/dst frame lengths
- dlens = dlens || corrlen(tfrms,*bref);
- if(bdst) dlens = dlens || corrlen(tfrms,*bdst);
-
- // check arg frame length
- if(barg) dalens = dalens || corrlen(afrms,*barg);
-
- ret->Src(ci,bref);
- if(bdst) ret->Dst(ci,bdst);
- }
-
- if(dlens) post("%s - vector src/dst length has been limited to maximum common length (%i)",op,tfrms);
- if(dalens) post("%s - vector arg length has been limited to maximum common length (%i)",op,afrms);
-
- if(ssize) {
- if(corrlen(tfrms,afrms))
- post("%s - vector src/dst and arg lengths are unequal -> set to max. common length (%i)",op,tfrms);
- afrms = tfrms;
- }
-
- ret->Frames(tfrms < 0?0:tfrms);
- ret->ArgFrames(afrms < 0?0:afrms);
-
- if(ok) return ret;
- else { delete ret; return NULL; }
-}
-
-
-/*! \brief Make real complex block for binary operations.
-
- \param op operation name
- \param src source vasp
- \param arg argument vasp
- \param dst optional destination vasp
- \param multi 0 off/1 on/-1 auto... controls whether argument vector is single- or multi-vectored
- \param full true if imaginary part is compulsory
- \return struct with vector data
-*/
-CVecBlock *VaspOp::GetCVecs(const C *op,CVasp &src,const CVasp &arg,CVasp *dst,I multi,BL ssize,BL full)
-{
- if(!arg.Ok()) {
- post("%s - invalid argument vasp detected and ignored",op);
- return NULL;
- }
-
- I nvecs = src.Vectors();
- if(dst && dst->Ok() && dst->Vectors() != nvecs) {
- nvecs = min(nvecs,dst->Vectors());
- post("%s - src/dst vector number not equal -> taking minimum",op);
- }
-
- I pairs = nvecs/2;
- CVecBlock *ret;
-
- if(multi < 0) { // auto mode
- multi = arg.Vectors() > 2; // more than one argument pair -> multi
- }
-
- if(multi) {
- I apairs = arg.Vectors()/2;
- if(arg.Vectors() != apairs*2)
- if(full) {
- post("%s - number of arg vectors is odd - not allowed",op);
- return NULL;
- }
- else {
- post("%s - number of arg vectors is odd - assuming complex part as 0",op);
- ++apairs;
- }
-
- if(apairs < pairs) {
- pairs = apairs;
- post("%s - too few arg vectors, operating on only first %i vector pairs",op,pairs);
- }
- ret = new CVecBlock(pairs,pairs,1);
- for(I i = 0; i < pairs; ++i)
- ret->Arg(i,arg.Buffer(i*2),arg.Buffer(i*2+1));
- }
- else {
- if(arg.Vectors() > 2) {
- post("%s - using only first arg vector pair for all operations",op);
- }
- ret = new CVecBlock(pairs,pairs,1);
- for(I i = 0; i < pairs; ++i)
- ret->Arg(i,arg.Buffer(0),arg.Buffer(1));
- }
-
- BL ok = true,dlens = false,dalens = false;
- I tfrms = -1,afrms = -1;
-
- {
- if(nvecs != pairs*2) {
- post("%s - number of src vectors is odd - omitting last vector",op);
- // clear superfluous vector?
- }
-
- for(I ci = 0; ok && ci < pairs; ++ci) {
- // --- arg stuff ----------------
-
- VBuffer *brarg = ret->ReArg(ci),*biarg = ret->ImArg(ci);
-
- if(multi || ci == 0) {
- if(!brarg->Data()) {
- post("%s - real arg vector (%s) is invalid",op,brarg->Name());
- ok = false; break;
- }
- else if(biarg && !biarg->Data()) {
- post("%s - imag arg vector (%s) is invalid",op,biarg->Name());
- ok = false; break;
- }
- }
-
- // check against common arg length
- if(brarg) dalens = dalens || corrlen(afrms,*brarg);
- if(biarg) dalens = dalens || corrlen(afrms,*biarg);
-
- // --- src/dst stuff ----------------
-
- VBuffer *brref = src.Buffer(ci*2),*biref = src.Buffer(ci*2+1);
- VBuffer *brdst,*bidst;
- if(dst && dst->Ok()) brdst = dst->Buffer(ci*2),bidst = dst->Buffer(ci*2+1);
- else brdst = bidst = NULL;
-
- if(!brref->Data()) {
- post("%s - real src vector (%s) is invalid",op,brref->Name());
- ok = false; break; // really break?
- }
- else if(biref && !biref->Data()) {
- post("%s - imag src vector (%s) is invalid",op,biref->Name());
- ok = false; break; // really break?
- }
- else {
- dlens = dlens || corrlen(tfrms,*brref);
- if(biref) dlens = dlens || corrlen(tfrms,*biref);
- if(brdst) dlens = dlens || corrlen(tfrms,*brdst);
- if(bidst) dlens = dlens || corrlen(tfrms,*bidst);
- }
-
- ret->Src(ci,brref,biref);
- if(brdst) ret->Dst(ci,brdst,bidst);
- }
- }
-
- if(dlens) post("%s - vector src/dst length has been limited to maximum common length (%i)",op,tfrms);
- if(dalens) post("%s - vector arg length has been limited to maximum common length (%i)",op,afrms);
-
- if(ssize) {
- if(corrlen(tfrms,afrms))
- post("%s - vector src/dst and arg lengths are unequal -> set to max. common length (%i)",op,tfrms);
- afrms = tfrms;
- }
-
- ret->Frames(tfrms < 0?0:tfrms);
- ret->ArgFrames(afrms < 0?0:afrms);
-
- if(ok) return ret;
- else { delete ret; return NULL; }
-}
-
-
-/*! \brief Run the operation on the various real vectors.
-
- \param vecs src/arg/dst vector block
- \param fun operative function
- \param p parameter block for operative function
- \return normalized vasp or NULL on error
-
- \todo set overlap flag
-
- \remark operative function must be capable of handling reversed direction
-*/
-Vasp *VaspOp::DoOp(RVecBlock *vecs,opfun *fun,OpParam &p,BL symm)
-{
- BL ok = true;
-
- if(vecs->ArgBlks() && (!p.arg || p.args < vecs->ArgBlks())) {
- post("%s - not enough argument blocks",p.opname);
- ok = false;
- }
-
- const I scnt = symm?2:1;
- for(I i = 0; ok && i < vecs->Vecs(); ++i)
- for(I si = 0; ok && si < scnt; ++si) {
- p.frames = vecs->Frames();
-
- VBuffer *s = vecs->Src(i),*d = vecs->Dst(i);
- p.rsdt = s->Pointer(),p.rss = s->Channels();
-
- if(d) p.rddt = d->Pointer(),p.rds = d->Channels();
- else p.rddt = p.rsdt,p.rds = p.rss;
-
- for(I bi = 0; bi < vecs->ArgBlks(); ++bi) {
- VBuffer *a = vecs->Arg(i,bi);
- p.arg[bi].SetV(a?a->Pointer():NULL,a?a->Channels():0);
- }
-
- if(!symm)
- p.symm = -1;
- else {
- const I hcnt = p.frames/2;
- p.oddrem = p.frames != 2*hcnt;
-
- if((p.symm = si) == 0) {
- p.frames = hcnt+(p.oddrem?1:0);
- }
- else {
- const I r = p.frames-hcnt;
- p.frames = hcnt;
- p.rsdt += r*p.rss,p.rddt += r*p.rds;
-
- // What to do with arguments in symmetric mode?
- // let the object decide!!
- }
- }
-
- { // ---- Check out and try to resolve overlap situation ------------
-
- BL sovr = p.SR_In(); // check whether dst is before src
- if(p.HasArg()) {
- // has argument
- if(sovr) {
- // src/dst needs reversal -> check if ok for arg/dst
- p.ovrlap = true;
-
- if(p.AR_Can())
- p.R_Rev(); // Revert vectors
- else {
- post("%s - vector overlap situation can't be resolved",p.opname);
- ok = false;
- }
- }
- else if(p.AR_In()) {
- // arg/dst needs reversal -> check if ok for src/dst
- p.ovrlap = true;
-
- if(p.SR_Can())
- p.R_Rev(); // Revert vectors
- else {
- post("%s - vector overlap situation can't be resolved",p.opname);
- ok = false;
- }
- }
- }
- else { // No arg
- if(sovr) {
- p.ovrlap = true;
- p.R_Rev(); // if overlapping revert vectors
- }
- else
- p.ovrlap = p.SR_Ovr();
- }
- }
-
- ok = fun(p);
-
-#ifdef FLEXT_THREAD
- flext_base::ThrYield();
-#endif
- }
- return ok?vecs->ResVasp():NULL;
-}
-
-
-/*! \brief Run the operation on the various complex vector pairs.
-
- \param vecs src/arg/dst vector block
- \param fun operative function
- \param p parameter block for operative function
- \return normalized vasp or NULL on error
-
- \todo set overlap flag
-
- \remark operative function must be capable of handling reversed direction
-*/
-Vasp *VaspOp::DoOp(CVecBlock *vecs,opfun *fun,OpParam &p,BL symm)
-{
- BL ok = true;
-
- if(vecs->ArgBlks() && (!p.arg || p.args < vecs->ArgBlks())) {
- post("%s - not enough argument blocks",p.opname);
- ok = false;
- }
-
- const I scnt = symm?2:1;
- for(I i = 0; ok && i < vecs->Pairs(); ++i)
- for(I si = 0; ok && si < scnt; ++si) {
- p.frames = vecs->Frames();
-
- VBuffer *rsv = vecs->ReSrc(i),*isv = vecs->ImSrc(i);
- p.rsdt = rsv->Pointer(),p.rss = rsv->Channels();
- p.isdt = isv->Pointer(),p.iss = isv->Channels();
-
- VBuffer *rdv = vecs->ReDst(i),*idv = vecs->ImDst(i);
- if(rdv) {
- p.rddt = rdv->Pointer(),p.rds = rdv->Channels();
- if(idv) p.iddt = idv->Pointer(),p.ids = idv->Channels();
- else p.iddt = NULL; //,p.ids = 0; // Can that be NULL??
- }
- else {
- p.rddt = p.rsdt,p.rds = p.rss,p.iddt = p.isdt,p.ids = p.iss;
- }
-
- for(I bi = 0; bi < vecs->ArgBlks(); ++bi) {
- VBuffer *rav = vecs->ReArg(i,bi),*iav = vecs->ImArg(i,bi);
- p.arg[bi].SetV(rav?rav->Pointer():NULL,rav?rav->Channels():0,iav?iav->Pointer():NULL,iav?iav->Channels():0);
- }
-
- if(!symm)
- p.symm = -1;
- else {
- const I hcnt = p.frames/2;
- p.oddrem = p.frames != 2*hcnt;
-
- if((p.symm = si) == 0) {
- p.frames = hcnt+(p.oddrem?1:0);
- }
- else {
- const I r = p.frames-hcnt;
- p.frames = hcnt;
- p.rsdt += r*p.rss,p.isdt += r*p.iss;
- p.rddt += r*p.rds;
- if(p.iddt) p.iddt += r*p.ids; // Can that be NULL??
-
- // What to do with arguments?
- // let objects decide!!
- }
- }
-
- { // ---- Check out and try to resolve overlap situation ------------
-
- BL sovr = p.SR_In(); // check whether dst is before src
- if(sovr && !p.SI_Can()) {
- post("%s - src/dst overlap of re/im vectors not resolvable",p.opname);
- ok = false;
- }
-
- if(ok && p.HasArg()) {
- // has argument
- if(sovr) {
- // src/dst needs reversal -> check if ok for arg/dst
- p.ovrlap = true;
-
- if(p.AR_Can() && p.AI_Can())
- p.C_Rev(); // Revert vectors
- else {
- post("%s - vector overlap situation can't be resolved",p.opname);
- ok = false;
- }
- }
- else if(p.AR_In() || p.AI_In()) {
- // arg/dst needs reversal -> check if ok for src/dst
- p.ovrlap = true;
-
- if(p.AR_Can() && p.AI_Can() && p.SR_Can() && p.SI_Can())
- p.C_Rev(); // Revert vectors
- else {
- post("%s - vector overlap situation can't be resolved",p.opname);
- ok = false;
- }
- }
- }
- else { // No arg
- if(sovr) {
- p.ovrlap = true;
- p.C_Rev(); // if overlapping revert vectors
- }
- else
- p.ovrlap = p.SR_Ovr() || p.SI_Ovr();
- }
- }
-
- ok = fun(p);
-
-#ifdef FLEXT_THREAD
- flext_base::ThrYield();
-#endif
- }
- return ok?vecs->ResVasp():NULL;
-}
-
-
-