Comments (9)
I'm pretty sure this would be "fixed" by removing these lines, but the problem is that there are a lot of widespread assumptions about the value of mechanisms always being 2d, so it's not quite that simple. If it would help, we could cast the default value for a function assigned to a mechanism to 2d, until we have more time to work on the main issue.
index d7ad5a524..43974c6eb 100644
--- a/psyneulink/components/mechanisms/mechanism.py
+++ b/psyneulink/components/mechanisms/mechanism.py
@@ -2219,26 +2219,7 @@ class Mechanism_Base(Mechanism):
context=context,
)
- # IMPLEMENTATION NOTE: THIS IS HERE BECAUSE IF return_value IS A LIST, AND THE LENGTH OF ALL OF ITS
- # ELEMENTS ALONG ALL DIMENSIONS ARE EQUAL (E.G., A 2X2 MATRIX PAIRED WITH AN
- # ARRAY OF LENGTH 2), np.array (AS WELL AS np.atleast_2d) GENERATES A ValueError
- if (isinstance(return_value, list) and
- (all(isinstance(item, np.ndarray) for item in return_value) and
- all(
- all(item.shape[i]==return_value[0].shape[0]
- for i in range(len(item.shape)))
- for item in return_value))):
-
- return return_value
- else:
- converted_to_2d = np.atleast_2d(return_value)
- # If return_value is a list of heterogenous elements, return as is
- # (satisfies requirement that return_value be an array of possibly multidimensional values)
- if converted_to_2d.dtype == object:
- return return_value
- # Otherwise, return value converted to 2d np.array
- else:
- return converted_to_2d
+ return return_value
# Call only subclass' function during initialization (not its full _execute method nor rest of this method)
elif self.initMethod is INIT_FUNCTION_METHOD_ONLY:
@@ -2291,27 +2272,6 @@ class Mechanism_Base(Mechanism):
context=context
)
- # IMPLEMENTATION NOTE: THIS IS HERE BECAUSE IF return_value IS A LIST, AND THE LENGTH OF ALL OF ITS
- # ELEMENTS ALONG ALL DIMENSIONS ARE EQUAL (E.G., A 2X2 MATRIX PAIRED WITH AN
- # ARRAY OF LENGTH 2), np.array (AS WELL AS np.atleast_2d) GENERATES A ValueError
- if (isinstance(value, list) and
- (all(isinstance(item, np.ndarray) for item in value) and
- all(
- all(item.shape[i]==value[0].shape[0]
- for i in range(len(item.shape)))
- for item in value))):
- pass
- else:
- converted_to_2d = np.atleast_2d(value)
- # If return_value is a list of heterogenous elements, return as is
- # (satisfies requirement that return_value be an array of possibly multidimensional values)
- if converted_to_2d.dtype == object:
- pass
- # Otherwise, return value converted to 2d np.array
- else:
- # return converted_to_2d
- value = converted_to_2d
-
# Set status based on whether self.value has changed
self.status = value
from psyneulink.
If "mechanism value is 2d" and "function_object value matches mechanism value" should both be preserved than casting the value looks like a solution to me.
Current compilation code relies on the latter. It's not difficult to adapt if such a guarantee is too cumbersome to maintain, but it simplifies the code.
from psyneulink.
I'm about to merge in a commit that would do this casting, though not for Reinforcement and BackPropagation functions because of what they return. Some casual testing hasn't found any mismatches for these functions, but if you find any, reopen this issue/let me know.
from psyneulink.
The commit (c040883) turns LCControlMechanism output into 3d structure:
>>> import psyneulink as pnl
>>> A = pnl.LCControlMechanism(default_variable=10.0)
>>> print(A.instance_defaults.value)
(array([[ 0.5]]), array([[ 0.]]), array([[ 0.]]), array([ 0.]))
The double arrays look redundant. Was the change in format intentional?
If it was, would vector values expand in the first or second dimension of the 2d array?
from psyneulink.
It seems that my first attempt maybe went too far. Several Functions return tuples, and in these cases I'm not sure what the right conversion is or if it even makes sense to convert. (FHNIntegrator used by LCControlMechanism is this example). Also in DDM, matching the function value and mechanism value seems not easy to do in a general way at the Function level considering how the mechanism value is constructed.
Is it helpful to keep the casting for most normal functions if you still have to workaround a few cases like above?
from psyneulink.
This report was the last remaining inconsistency that I ran into. I'm not sure what the correct solution for PsyNeuLink is. The more general solution the better so I don't have to special case situations (I think the python codepaths benefit from this as well).
On a high level, I expect that the result for the last function in a mechanism (is that always self.function_object?) can be passed to output state parsing function (as specified by parse_variable_spec function).
I think the LCControlMechanism value format matched the function value format (otherwise I'd need a workaround for that as well), so my take is that the functions that return multiple values don't need conversion.
from psyneulink.
Ok. I think making a fully correct and general solution would take significant effort and design, and probably should be considered when/if the 2d restriction on mechanism values is lifted. So, if the latest changes in 17b09bf will work for you without workarounds then I'll leave it at that for now.
from psyneulink.
Thank you. with current devel and 17b09bf I can remove the last output shape workaround and pass all the tests.
from psyneulink.
I could remove the workaround in db76513.
Thank you.
from psyneulink.
Related Issues (20)
- Behavior for conflicts between shared parameters
- Potential for false-passing tests due to np.allclose use
- Integrate more optimization algorithms into PEC HOT 2
- MCMC
- using torch<1.12.0 fails cross_entropy tests
- Support for Python 3.11 HOT 2
- Components should be reset when state changes are not due to execution
- Standardize component constructor params/param_defaults/kwargs
- TransferWithCosts: Intensity cost is `[1]` even when intensity cost is disabled HOT 1
- TransferWithCosts: Shape of the variable of the combination function is always single element array
- Missing line from documentation comment HOT 1
- ControlSignal costs are calculated twice HOT 7
- incorrect warning about missing afferent projections
- log nparray() drops entries with duplicate time points. HOT 2
- Intermittent failures in `test_parameter_optimization_ddm[LLVM-optuna_cmaes_sampler]` HOT 5
- [Python 3.12] Embedded versioneer doesn't support Python 3.12 HOT 1
- Add support for Python 3.12 HOT 1
- Failures in mdf test using numpy 1.25+ HOT 1
- Learning resources HOT 9
- PEC not working with new stability flexibility version HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from psyneulink.