-1

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.

Felipe
  • 479
  • 8
  • This may be what you are looking for: ds = CreateDataStructure["DynamicArray"] See the documentation for DataStructures. HTH. – Craig Carter Mar 02 '24 at 15:52
  • 2
    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. – Nasser Mar 02 '24 at 15:52
  • 2
    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? – lericr Mar 02 '24 at 16:09
  • @Nasser I don't have any particular example in mind, I am mostly looking a way to deactivate this system feature momentarily. However, a similar problem happened in this stack about matrix vector multiplication, where in order to avoid copy, a fortran code was called to do the multiplication. I want to know if there is a way to do it without leaving mathematica. You can use this example if it helps. – Felipe Mar 02 '24 at 16:09
  • @CraigCarter Thanks, I will give a look to it. – Felipe Mar 02 '24 at 16:10
  • @lericr I am no specialist, this is what I learned from some books like Leonid Shiffrin's and David Wagner's book on how mathematica operates. It may be that in my example there would be no copy creation, but as far as I know in general there is, for instance in this stack. – Felipe Mar 02 '24 at 16:23
  • @lericr About the localization solution, I learned from Wagner's book, and avoids the copy problem, but he showed that doesn't scale as well as functional, so I wanted something that got "the best of both worlds", so to speak. The functional optimization, and the absence of copies. – Felipe Mar 02 '24 at 16:25
  • 3
    @Felipe As it is, with no specific reproducible example leading to a problem, your question is unfortunately practically unanswerable. – MarcoB Mar 03 '24 at 02:07
  • @MarcoB the example is the link I posted as an eddit, where it was concluded that the system was internally copying. That is the behavior I want to block, without calling other languages as it was done in the other stack. – Felipe Mar 03 '24 at 10:18
  • 1
    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. – Domen Mar 04 '24 at 11:35
  • @Domen Yeah, I didn't went into big depths about it because it looked like a pass-by-reference at the higher language level for me (maybe I didn't went in depth enough on these stacks), about the mathematica evaluation process and so on. I am asking about the system level, you have the process of replacing one expression by another and so on, but when it does replace there is a internal function call in C that calculates what the new expression should be. I want to block this function to pass by value. – Felipe Mar 04 '24 at 11:45

2 Answers2

3

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 *)

Goofy
  • 2,767
  • 10
  • 12
  • This may be what I am looking for, do you know if it is a "pass-by-reference" call? Internally – Felipe Mar 04 '24 at 11:36
  • 2
    @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. – Goofy Mar 04 '24 at 12:50
  • Cool, thanks a lot. – Felipe Mar 04 '24 at 19:02
0

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.

Craig Carter
  • 4,416
  • 16
  • 28
  • 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. – Felipe Mar 04 '24 at 11:32