-1
$\begingroup$

I am reformulating the question since it was apparently unclear. One of the comments made me find the correct programming language "syntax" for what I wanted to do(Thanks Nasser).

In this stack it was found that mathematica is slow in matrix-scalar multiplications because it copies inputs before executing the requested operation. This looks like a "pass-by-value" function call, they solved the problem by calling an external Fortran library and using "shared" which avoided the copying of input. In other words, the solution looked like a "pass-by-reference" for me.

My question: is there a way to "pass-by-reference" without leaving mathematica? I want to do that at the C-code level, to insure that no copying is taking place.

It is not obvious at the user end if copying is taking place internally or not, it certainly wasn't for me at the beginning of the referenced stack, so a way to see if that is the case would be most welcome.

$\endgroup$
11
  • $\begingroup$ This may be what you are looking for: ds = CreateDataStructure["DynamicArray"] See the documentation for DataStructures. HTH. $\endgroup$ Mar 2 at 15:52
  • 2
    $\begingroup$ To be able to give a better answer, you really need to give an example code to help explain things and the context. For passing arguments to function, there is a way to pass things by reference instead of by value if this is what you mean. $\endgroup$
    – Nasser
    Mar 2 at 15:52
  • 2
    $\begingroup$ It's not at all clear from your example that there would be any creating of copies and acting on the copies. And actually, I don't think that's an accurate description of what Mathematica's evaluation engine actually does (except maybe at the lowest, internal, C++ [or whatever language] level). And furthermore, you've already identified "localization" as a possibility--Module might be better than Block--which would clean up temporary variables (if that's even what you're concerned about). Are you running into some actual problem that you can describe? $\endgroup$
    – lericr
    Mar 2 at 16:09
  • 3
    $\begingroup$ @Felipe As it is, with no specific reproducible example leading to a problem, your question is unfortunately practically unanswerable. $\endgroup$
    – MarcoB
    Mar 3 at 2:07
  • 1
    $\begingroup$ Regarding your edit: Have you read any of the questions and answers about passing by reference on this SE? How to pass variables by reference and by value, Passing large list by reference ... Also, I don't think you should focus so much on this particular concept, since it is not very common in Mathematica. It is better to give concrete examples of your code and find optimizations for them. $\endgroup$
    – Domen
    Mar 4 at 11:35

2 Answers 2

3
$\begingroup$

Maybe you could use BLAS, which tends to do in-place operations.

a = RandomReal[1, {100000000}];
b = a;
a[[1]] = 0.1; b[[1]] = 0.1;
AbsoluteTiming[LinearAlgebra`BLAS`SCAL[0.3, a];]
AbsoluteTiming[c = 0.3 b;]
a == c
Clear[a, b, c]

(*
{0.008628, Null}

{0.030183, Null}

True
*)
$\endgroup$
3
  • $\begingroup$ This may be what I am looking for, do you know if it is a "pass-by-reference" call? Internally $\endgroup$
    – Felipe
    Mar 4 at 11:36
  • 2
    $\begingroup$ @Felipe Probably. Attributes@LinearAlgebra`BLAS`SCAL has the HoldAll attribute, which means that the arguments are passed by reference. I don't know how you can be sure a developer didn't do something stupid in the internal code. I doubt they did, though. This sort of efficiency is the point of incorporating BLAS/LAPACK into the underlying linear algebra engine. $\endgroup$
    – Goofy
    Mar 4 at 12:50
  • $\begingroup$ Cool, thanks a lot. $\endgroup$
    – Felipe
    Mar 4 at 19:02
0
$\begingroup$

I am not sure what the question is, so this or may not be in the ballpark for an answer. Here is a usage example and timings for the DataStructure "DynamicArray"

$System
$Version
(*"Mac OS X ARM (64-bit)" "14.0.0 for Mac OS X ARM (64-bit) (December 13, 2023)"*)

    AbsoluteTiming[
     normalList = RandomReal[1, 10^8];
     ]
(*{0.378017, Null}*)

More expensive to create:

AbsoluteTiming[
 ds = CreateDataStructure["DynamicArray", RandomReal[1, 10^8]];
 ]
(*{25.1532, Null}*)

Less expensive to set a part:

AbsoluteTiming[normalList[[100]] = 1;]
(*{1.11274, Null}*)

AbsoluteTiming[ds["SetPart", 100, 1];]
(*{9.*10^-6, Null}*)

Less expensive to append:

AbsoluteTiming[AppendTo[normalList, 1];]
(*{0.323772, Null}*)

AbsoluteTiming[ds["Append", 100];]
(*{7.*10^-6, Null}*)

More expensive to extract:

AbsoluteTiming[normalList[[100]]]
(* {4.*10^-6, 1}*)

AbsoluteTiming[ds["Part", 100]]
(* {0.00002, 1} *)

This leads me to believe that the data structures are accessing memory and not making copies. Perhaps that is in the documentation, but I haven't read it completely.

$\endgroup$
1
  • $\begingroup$ Not exactly what I was looking, I found the word for what I was thinking (I am new to programming, not familiar with all the terms yet) it is pass by reference, at the internal mathematica code level. $\endgroup$
    – Felipe
    Mar 4 at 11:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.